<!DOCTYPE html><html lang="zh-CN" data-theme="light"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0,viewport-fit=cover"><title>MiniShell | Jixer的小屋</title><meta name="author" content="Jixer"><meta name="copyright" content="Jixer"><meta name="format-detection" content="telephone=no"><meta name="theme-color" content="#ffffff"><meta name="description" content="作业名称：MiniShell功能要求：编写一个类似ubuntu terminal的程序  ChatGPT YYDS  Java版本123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172">
<meta property="og:type" content="article">
<meta property="og:title" content="MiniShell">
<meta property="og:url" content="http://www.lijunxi.site/posts/2960345248/index.html">
<meta property="og:site_name" content="Jixer的小屋">
<meta property="og:description" content="作业名称：MiniShell功能要求：编写一个类似ubuntu terminal的程序  ChatGPT YYDS  Java版本123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://q1.qlogo.cn/g?b=qq&nk=2770063826&s=640">
<meta property="article:published_time" content="2024-01-16T16:38:34.000Z">
<meta property="article:modified_time" content="2024-05-07T03:10:23.256Z">
<meta property="article:author" content="Jixer">
<meta property="article:tag" content="Linux">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://q1.qlogo.cn/g?b=qq&nk=2770063826&s=640"><link rel="shortcut icon" href="/img/logo/favicon.ico"><link rel="canonical" href="http://www.lijunxi.site/posts/2960345248/index.html"><link rel="preconnect"/><link rel="preconnect" href="//busuanzi.ibruce.info"/><link rel="stylesheet" href="/css/index.css?v=4.13.0"><link rel="stylesheet" href="/pluginsSrc/@fortawesome/fontawesome-free/css/all.min.css?v=6.5.1"><link rel="stylesheet" href="/pluginsSrc/@fancyapps/ui/dist/fancybox/fancybox.css?v=5.0.33" media="print" onload="this.media='all'"><script>const GLOBAL_CONFIG = {
  root: '/',
  algolia: undefined,
  localSearch: {"path":"/search.xml","preload":true,"top_n_per_article":1,"unescape":false,"languages":{"hits_empty":"找不到您查询的内容：${query}","hits_stats":"共找到 ${hits} 篇文章"}},
  translate: undefined,
  noticeOutdate: undefined,
  highlight: {"plugin":"highlight.js","highlightCopy":true,"highlightLang":true,"highlightHeightLimit":false},
  copy: {
    success: '复制成功',
    error: '复制错误',
    noSupport: '浏览器不支持'
  },
  relativeDate: {
    homepage: false,
    post: false
  },
  runtime: '',
  dateSuffix: {
    just: '刚刚',
    min: '分钟前',
    hour: '小时前',
    day: '天前',
    month: '个月前'
  },
  copyright: undefined,
  lightbox: 'fancybox',
  Snackbar: undefined,
  infinitegrid: {
    js: '/pluginsSrc/@egjs/infinitegrid/dist/infinitegrid.min.js?v=4.11.1',
    buttonText: '加载更多'
  },
  isPhotoFigcaption: false,
  islazyload: false,
  isAnchor: false,
  percent: {
    toc: true,
    rightside: false,
  },
  autoDarkmode: false
}</script><script id="config-diff">var GLOBAL_CONFIG_SITE = {
  title: 'MiniShell',
  isPost: true,
  isHome: false,
  isHighlightShrink: false,
  isToc: true,
  postUpdate: '2024-05-07 11:10:23'
}</script><script>(win=>{
      win.saveToLocal = {
        set: (key, value, ttl) => {
          if (ttl === 0) return
          const now = Date.now()
          const expiry = now + ttl * 86400000
          const item = {
            value,
            expiry
          }
          localStorage.setItem(key, JSON.stringify(item))
        },
      
        get: key => {
          const itemStr = localStorage.getItem(key)
      
          if (!itemStr) {
            return undefined
          }
          const item = JSON.parse(itemStr)
          const now = Date.now()
      
          if (now > item.expiry) {
            localStorage.removeItem(key)
            return undefined
          }
          return item.value
        }
      }
    
      win.getScript = (url, attr = {}) => new Promise((resolve, reject) => {
        const script = document.createElement('script')
        script.src = url
        script.async = true
        script.onerror = reject
        script.onload = script.onreadystatechange = function() {
          const loadState = this.readyState
          if (loadState && loadState !== 'loaded' && loadState !== 'complete') return
          script.onload = script.onreadystatechange = null
          resolve()
        }

        Object.keys(attr).forEach(key => {
          script.setAttribute(key, attr[key])
        })

        document.head.appendChild(script)
      })
    
      win.getCSS = (url, id = false) => new Promise((resolve, reject) => {
        const link = document.createElement('link')
        link.rel = 'stylesheet'
        link.href = url
        if (id) link.id = id
        link.onerror = reject
        link.onload = link.onreadystatechange = function() {
          const loadState = this.readyState
          if (loadState && loadState !== 'loaded' && loadState !== 'complete') return
          link.onload = link.onreadystatechange = null
          resolve()
        }
        document.head.appendChild(link)
      })
    
      win.activateDarkMode = () => {
        document.documentElement.setAttribute('data-theme', 'dark')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', '#0d0d0d')
        }
      }
      win.activateLightMode = () => {
        document.documentElement.setAttribute('data-theme', 'light')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', '#ffffff')
        }
      }
      const t = saveToLocal.get('theme')
    
        if (t === 'dark') activateDarkMode()
        else if (t === 'light') activateLightMode()
      
      const asideStatus = saveToLocal.get('aside-status')
      if (asideStatus !== undefined) {
        if (asideStatus === 'hide') {
          document.documentElement.classList.add('hide-aside')
        } else {
          document.documentElement.classList.remove('hide-aside')
        }
      }
    
      const detectApple = () => {
        if(/iPad|iPhone|iPod|Macintosh/.test(navigator.userAgent)){
          document.documentElement.classList.add('apple')
        }
      }
      detectApple()
    })(window)</script><link rel="stylesheet" href="/css/custom-all-min.css"><link rel="stylesheet" href="/css/custom-fancybox-min.css"><link rel="stylesheet" href="/css/custom-share-min.css"><meta name="generator" content="Hexo 6.3.0"></head><body><div id="loading-box"><div class="loading-left-bg"></div><div class="loading-right-bg"></div><div class="spinner-box"><div class="configure-border-1"><div class="configure-core"></div></div><div class="configure-border-2"><div class="configure-core"></div></div><div class="loading-word">加载中...</div></div></div><script>(()=>{
  const $loadingBox = document.getElementById('loading-box')
  const $body = document.body
  const preloader = {
    endLoading: () => {
      $body.style.overflow = ''
      $loadingBox.classList.add('loaded')
    },
    initLoading: () => {
      $body.style.overflow = 'hidden'
      $loadingBox.classList.remove('loaded')
    }
  }

  preloader.initLoading()
  window.addEventListener('load',() => { preloader.endLoading() })

  if (false) {
    document.addEventListener('pjax:send', () => { preloader.initLoading() })
    document.addEventListener('pjax:complete', () => { preloader.endLoading() })
  }
})()</script><div id="sidebar"><div id="menu-mask"></div><div id="sidebar-menus"><div class="avatar-img is-center"><img src="" data-original="https://q1.qlogo.cn/g?b=qq&amp;nk=2770063826&amp;s=640" onerror="onerror=null;src='/img/friend_404.gif'" alt="avatar"/></div><div class="sidebar-site-data site-data is-center"><a href="/archives/"><div class="headline">文章</div><div class="length-num">52</div></a><a href="/tags/"><div class="headline">标签</div><div class="length-num">19</div></a><a href="/categories/"><div class="headline">分类</div><div class="length-num">7</div></a></div><hr class="custom-hr"/><div class="menus_items"><div class="menus_item"><a class="site-page" href="/"><i class="fa-fw fas fa-home"></i><span> 主页</span></a></div><div class="menus_item"><a class="site-page group" href="javascript:void(0);"><i class="fa-fw fa fa-graduation-cap"></i><span> 文章</span><i class="fas fa-chevron-down"></i></a><ul class="menus_item_child"><li><a class="site-page child" href="/categories/"><i class="fa-fw fa fa-archive"></i><span> 分类</span></a></li><li><a class="site-page child" href="/tags/"><i class="fa-fw fa fa-tags"></i><span> 标签</span></a></li><li><a class="site-page child" href="/archives/"><i class="fa-fw fa fa-folder-open"></i><span> 归档</span></a></li></ul></div><div class="menus_item"><a class="site-page" href="/links/"><i class="fa-fw fa fa-link"></i><span> 友链</span></a></div><div class="menus_item"><a class="site-page" href="/about/"><i class="fa-fw fas fa-heart"></i><span> 关于</span></a></div></div></div></div><div class="post" id="body-wrap"><header class="post-bg" id="page-header"><nav id="nav"><span id="blog-info"><a href="/" title="Jixer的小屋"><span class="site-name">Jixer的小屋</span></a></span><div id="menus"><div id="search-button"><a class="site-page social-icon search" href="javascript:void(0);"><i class="fas fa-search fa-fw"></i><span> 搜索</span></a></div><div class="menus_items"><div class="menus_item"><a class="site-page" href="/"><i class="fa-fw fas fa-home"></i><span> 主页</span></a></div><div class="menus_item"><a class="site-page group" href="javascript:void(0);"><i class="fa-fw fa fa-graduation-cap"></i><span> 文章</span><i class="fas fa-chevron-down"></i></a><ul class="menus_item_child"><li><a class="site-page child" href="/categories/"><i class="fa-fw fa fa-archive"></i><span> 分类</span></a></li><li><a class="site-page child" href="/tags/"><i class="fa-fw fa fa-tags"></i><span> 标签</span></a></li><li><a class="site-page child" href="/archives/"><i class="fa-fw fa fa-folder-open"></i><span> 归档</span></a></li></ul></div><div class="menus_item"><a class="site-page" href="/links/"><i class="fa-fw fa fa-link"></i><span> 友链</span></a></div><div class="menus_item"><a class="site-page" href="/about/"><i class="fa-fw fas fa-heart"></i><span> 关于</span></a></div></div><div id="toggle-menu"><a class="site-page" href="javascript:void(0);"><i class="fas fa-bars fa-fw"></i></a></div></div></nav><div id="post-info"><h1 class="post-title">MiniShell</h1><div id="post-meta"><div class="meta-firstline"><span class="post-meta-date"><i class="far fa-calendar-alt fa-fw post-meta-icon"></i><span class="post-meta-label">发表于</span><time class="post-meta-date-created" datetime="2024-01-16T16:38:34.000Z" title="发表于 2024-01-17 00:38:34">2024-01-17</time><span class="post-meta-separator">|</span><i class="fas fa-history fa-fw post-meta-icon"></i><span class="post-meta-label">更新于</span><time class="post-meta-date-updated" datetime="2024-05-07T03:10:23.256Z" title="更新于 2024-05-07 11:10:23">2024-05-07</time></span></div><div class="meta-secondline"><span class="post-meta-separator">|</span><span class="post-meta-wordcount"><i class="far fa-file-word fa-fw post-meta-icon"></i><span class="post-meta-label">字数总计:</span><span class="word-count">5.3k</span><span class="post-meta-separator">|</span><i class="far fa-clock fa-fw post-meta-icon"></i><span class="post-meta-label">阅读时长:</span><span>28分钟</span></span><span class="post-meta-separator">|</span><span class="post-meta-pv-cv" id="" data-flag-title="MiniShell"><i class="far fa-eye fa-fw post-meta-icon"></i><span class="post-meta-label">阅读量:</span><span id="busuanzi_value_page_pv"><i class="fa-solid fa-spinner fa-spin"></i></span></span></div></div></div></header><main class="layout" id="content-inner"><div id="post"><article class="post-content" id="article-container"><p>作业名称：<strong>MiniShell</strong><br>功能要求：<strong>编写一个类似ubuntu terminal的程序</strong></p>
<blockquote>
<p>ChatGPT YYDS</p>
</blockquote>
<h2 id="Java版本"><a href="#Java版本" class="headerlink" title="Java版本"></a>Java版本</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br><span class="line">220</span><br><span class="line">221</span><br><span class="line">222</span><br><span class="line">223</span><br><span class="line">224</span><br><span class="line">225</span><br><span class="line">226</span><br><span class="line">227</span><br><span class="line">228</span><br><span class="line">229</span><br><span class="line">230</span><br><span class="line">231</span><br><span class="line">232</span><br><span class="line">233</span><br><span class="line">234</span><br><span class="line">235</span><br><span class="line">236</span><br><span class="line">237</span><br><span class="line">238</span><br><span class="line">239</span><br><span class="line">240</span><br><span class="line">241</span><br><span class="line">242</span><br><span class="line">243</span><br><span class="line">244</span><br><span class="line">245</span><br><span class="line">246</span><br><span class="line">247</span><br><span class="line">248</span><br><span class="line">249</span><br><span class="line">250</span><br><span class="line">251</span><br><span class="line">252</span><br><span class="line">253</span><br><span class="line">254</span><br><span class="line">255</span><br><span class="line">256</span><br><span class="line">257</span><br><span class="line">258</span><br><span class="line">259</span><br><span class="line">260</span><br><span class="line">261</span><br><span class="line">262</span><br><span class="line">263</span><br><span class="line">264</span><br><span class="line">265</span><br><span class="line">266</span><br><span class="line">267</span><br><span class="line">268</span><br><span class="line">269</span><br><span class="line">270</span><br><span class="line">271</span><br><span class="line">272</span><br><span class="line">273</span><br><span class="line">274</span><br><span class="line">275</span><br><span class="line">276</span><br><span class="line">277</span><br><span class="line">278</span><br><span class="line">279</span><br><span class="line">280</span><br><span class="line">281</span><br><span class="line">282</span><br><span class="line">283</span><br><span class="line">284</span><br><span class="line">285</span><br><span class="line">286</span><br><span class="line">287</span><br><span class="line">288</span><br><span class="line">289</span><br><span class="line">290</span><br><span class="line">291</span><br><span class="line">292</span><br><span class="line">293</span><br><span class="line">294</span><br><span class="line">295</span><br><span class="line">296</span><br><span class="line">297</span><br><span class="line">298</span><br><span class="line">299</span><br><span class="line">300</span><br><span class="line">301</span><br><span class="line">302</span><br><span class="line">303</span><br><span class="line">304</span><br><span class="line">305</span><br><span class="line">306</span><br><span class="line">307</span><br><span class="line">308</span><br><span class="line">309</span><br><span class="line">310</span><br><span class="line">311</span><br><span class="line">312</span><br><span class="line">313</span><br><span class="line">314</span><br><span class="line">315</span><br><span class="line">316</span><br><span class="line">317</span><br><span class="line">318</span><br><span class="line">319</span><br><span class="line">320</span><br><span class="line">321</span><br><span class="line">322</span><br><span class="line">323</span><br><span class="line">324</span><br><span class="line">325</span><br><span class="line">326</span><br><span class="line">327</span><br><span class="line">328</span><br><span class="line">329</span><br><span class="line">330</span><br><span class="line">331</span><br><span class="line">332</span><br><span class="line">333</span><br><span class="line">334</span><br><span class="line">335</span><br><span class="line">336</span><br><span class="line">337</span><br><span class="line">338</span><br><span class="line">339</span><br><span class="line">340</span><br><span class="line">341</span><br><span class="line">342</span><br><span class="line">343</span><br><span class="line">344</span><br><span class="line">345</span><br><span class="line">346</span><br><span class="line">347</span><br><span class="line">348</span><br><span class="line">349</span><br><span class="line">350</span><br><span class="line">351</span><br><span class="line">352</span><br><span class="line">353</span><br><span class="line">354</span><br><span class="line">355</span><br><span class="line">356</span><br><span class="line">357</span><br><span class="line">358</span><br><span class="line">359</span><br><span class="line">360</span><br><span class="line">361</span><br><span class="line">362</span><br><span class="line">363</span><br><span class="line">364</span><br><span class="line">365</span><br><span class="line">366</span><br><span class="line">367</span><br><span class="line">368</span><br><span class="line">369</span><br><span class="line">370</span><br><span class="line">371</span><br><span class="line">372</span><br><span class="line">373</span><br><span class="line">374</span><br><span class="line">375</span><br><span class="line">376</span><br><span class="line">377</span><br><span class="line">378</span><br><span class="line">379</span><br><span class="line">380</span><br><span class="line">381</span><br><span class="line">382</span><br><span class="line">383</span><br><span class="line">384</span><br><span class="line">385</span><br><span class="line">386</span><br><span class="line">387</span><br><span class="line">388</span><br><span class="line">389</span><br><span class="line">390</span><br><span class="line">391</span><br><span class="line">392</span><br><span class="line">393</span><br><span class="line">394</span><br><span class="line">395</span><br><span class="line">396</span><br><span class="line">397</span><br><span class="line">398</span><br><span class="line">399</span><br><span class="line">400</span><br><span class="line">401</span><br><span class="line">402</span><br><span class="line">403</span><br><span class="line">404</span><br><span class="line">405</span><br><span class="line">406</span><br><span class="line">407</span><br><span class="line">408</span><br><span class="line">409</span><br><span class="line">410</span><br><span class="line">411</span><br><span class="line">412</span><br><span class="line">413</span><br><span class="line">414</span><br><span class="line">415</span><br><span class="line">416</span><br><span class="line">417</span><br><span class="line">418</span><br><span class="line">419</span><br><span class="line">420</span><br><span class="line">421</span><br><span class="line">422</span><br><span class="line">423</span><br><span class="line">424</span><br><span class="line">425</span><br><span class="line">426</span><br><span class="line">427</span><br><span class="line">428</span><br><span class="line">429</span><br><span class="line">430</span><br><span class="line">431</span><br><span class="line">432</span><br><span class="line">433</span><br><span class="line">434</span><br><span class="line">435</span><br><span class="line">436</span><br><span class="line">437</span><br><span class="line">438</span><br><span class="line">439</span><br><span class="line">440</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> minShell;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.io.*;</span><br><span class="line"><span class="keyword">import</span> java.nio.file.*;</span><br><span class="line"><span class="keyword">import</span> java.util.zip.*;</span><br><span class="line"><span class="keyword">import</span> java.nio.file.Files;</span><br><span class="line"><span class="keyword">import</span> java.nio.file.Path;</span><br><span class="line"><span class="keyword">import</span> java.nio.file.Paths;</span><br><span class="line"><span class="keyword">import</span> java.nio.file.StandardCopyOption;</span><br><span class="line"><span class="keyword">import</span> java.nio.file.attribute.BasicFileAttributeView;</span><br><span class="line"><span class="keyword">import</span> java.nio.file.attribute.FileTime;</span><br><span class="line"><span class="keyword">import</span> java.nio.file.attribute.PosixFileAttributes;</span><br><span class="line"><span class="keyword">import</span> java.nio.file.attribute.PosixFilePermission;</span><br><span class="line"><span class="keyword">import</span> java.nio.file.attribute.PosixFilePermissions;</span><br><span class="line"><span class="keyword">import</span> java.text.SimpleDateFormat;</span><br><span class="line"><span class="keyword">import</span> java.time.Instant;</span><br><span class="line"><span class="keyword">import</span> java.util.*;</span><br><span class="line"><span class="keyword">import</span> java.util.zip.GZIPInputStream;</span><br><span class="line"><span class="keyword">import</span> java.util.zip.GZIPOutputStream;</span><br><span class="line"><span class="keyword">import</span> java.util.zip.ZipEntry;</span><br><span class="line"><span class="keyword">import</span> java.util.zip.ZipInputStream;</span><br><span class="line"><span class="keyword">import</span> java.util.zip.ZipOutputStream;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">minShell</span> &#123;</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">final</span> <span class="type">String</span> <span class="variable">CONFIG_FILE</span> <span class="operator">=</span> <span class="string">&quot;minShell.conf&quot;</span>;</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">final</span> <span class="type">String</span> <span class="variable">PROMPT_LONG</span> <span class="operator">=</span> <span class="string">&quot;long&quot;</span>;</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">final</span> <span class="type">String</span> <span class="variable">PROMPT_SHORT</span> <span class="operator">=</span> <span class="string">&quot;short&quot;</span>;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> String prompt;</span><br><span class="line">    <span class="keyword">private</span> String background;</span><br><span class="line">    <span class="keyword">private</span> String font;</span><br><span class="line">    <span class="keyword">private</span> <span class="type">int</span> fontSize;</span><br><span class="line">    <span class="keyword">private</span> String fontColor;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> List&lt;String&gt; commandHistory;</span><br><span class="line">    <span class="keyword">private</span> <span class="type">int</span> historyIndex;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="title function_">minShell</span><span class="params">()</span> &#123;</span><br><span class="line">        commandHistory = <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;();</span><br><span class="line">        historyIndex = <span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">loadConfiguration</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="type">Properties</span> <span class="variable">properties</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Properties</span>();</span><br><span class="line">        <span class="keyword">try</span> (<span class="type">InputStream</span> <span class="variable">input</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">FileInputStream</span>(CONFIG_FILE)) &#123;</span><br><span class="line">            properties.load(input);</span><br><span class="line">            prompt = properties.getProperty(<span class="string">&quot;promote&quot;</span>, PROMPT_LONG);</span><br><span class="line">            background = properties.getProperty(<span class="string">&quot;background&quot;</span>, <span class="string">&quot;black&quot;</span>);</span><br><span class="line">            font = properties.getProperty(<span class="string">&quot;font&quot;</span>, <span class="string">&quot;宋体&quot;</span>);</span><br><span class="line">            fontSize = Integer.parseInt(properties.getProperty(<span class="string">&quot;fontsize&quot;</span>, <span class="string">&quot;30&quot;</span>));</span><br><span class="line">            fontColor = properties.getProperty(<span class="string">&quot;fontcolor&quot;</span>, <span class="string">&quot;white&quot;</span>);</span><br><span class="line">        &#125; <span class="keyword">catch</span> (IOException e) &#123;</span><br><span class="line">            <span class="comment">// Configuration file not found or error reading file</span></span><br><span class="line">            <span class="comment">// Use default values</span></span><br><span class="line">            prompt = PROMPT_LONG;</span><br><span class="line">            background = <span class="string">&quot;black&quot;</span>;</span><br><span class="line">            font = <span class="string">&quot;宋体&quot;</span>;</span><br><span class="line">            fontSize = <span class="number">30</span>;</span><br><span class="line">            fontColor = <span class="string">&quot;white&quot;</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">saveConfiguration</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="type">Properties</span> <span class="variable">properties</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Properties</span>();</span><br><span class="line">        properties.setProperty(<span class="string">&quot;promote&quot;</span>, prompt);</span><br><span class="line">        properties.setProperty(<span class="string">&quot;background&quot;</span>, background);</span><br><span class="line">        properties.setProperty(<span class="string">&quot;font&quot;</span>, font);</span><br><span class="line">        properties.setProperty(<span class="string">&quot;fontsize&quot;</span>, String.valueOf(fontSize));</span><br><span class="line">        properties.setProperty(<span class="string">&quot;fontcolor&quot;</span>, fontColor);</span><br><span class="line"></span><br><span class="line">        <span class="keyword">try</span> (<span class="type">OutputStream</span> <span class="variable">output</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">FileOutputStream</span>(CONFIG_FILE)) &#123;</span><br><span class="line">            properties.store(output, <span class="string">&quot;miniShell Configuration&quot;</span>);</span><br><span class="line">        &#125; <span class="keyword">catch</span> (IOException e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">run</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="type">Scanner</span> <span class="variable">scanner</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Scanner</span>(System.in);</span><br><span class="line">        loadConfiguration();</span><br><span class="line"></span><br><span class="line">        <span class="keyword">while</span> (<span class="literal">true</span>) &#123;</span><br><span class="line">            displayPrompt();</span><br><span class="line">            <span class="type">String</span> <span class="variable">input</span> <span class="operator">=</span> scanner.nextLine();</span><br><span class="line">            commandHistory.add(input);</span><br><span class="line">            processCommand(input);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">void</span> <span class="title function_">displayPrompt</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (prompt.equals(PROMPT_LONG)) &#123;</span><br><span class="line">            <span class="type">String</span> <span class="variable">user</span> <span class="operator">=</span> System.getProperty(<span class="string">&quot;user.name&quot;</span>);</span><br><span class="line">            <span class="type">String</span> <span class="variable">host</span> <span class="operator">=</span> <span class="string">&quot;ljx-virtual-machine&quot;</span>;</span><br><span class="line">            System.out.print(user + <span class="string">&quot;@&quot;</span> + host + <span class="string">&quot;$ &quot;</span>);</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            System.out.print(<span class="string">&quot;$ &quot;</span>);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">void</span> <span class="title function_">processCommand</span><span class="params">(String command)</span> &#123;</span><br><span class="line">        String[] tokens = command.split(<span class="string">&quot;\\s+&quot;</span>);</span><br><span class="line">        <span class="keyword">if</span> (tokens.length == <span class="number">0</span>) &#123;</span><br><span class="line">            <span class="keyword">return</span>;</span><br><span class="line">        &#125;</span><br><span class="line">     </span><br><span class="line">        <span class="type">String</span> <span class="variable">commandName</span> <span class="operator">=</span> tokens[<span class="number">0</span>];</span><br><span class="line"></span><br><span class="line">        <span class="keyword">switch</span> (commandName) &#123;</span><br><span class="line">            <span class="keyword">case</span> <span class="string">&quot;ls&quot;</span>:</span><br><span class="line">                <span class="comment">// Handle ls command</span></span><br><span class="line">            	executeLs(tokens);</span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">            <span class="keyword">case</span> <span class="string">&quot;cd&quot;</span>:</span><br><span class="line">                <span class="comment">// Handle cd command</span></span><br><span class="line">                <span class="comment">// ...</span></span><br><span class="line">            	executeCd(tokens);</span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">            <span class="keyword">case</span> <span class="string">&quot;mkdir&quot;</span>:</span><br><span class="line">                <span class="comment">// Handle mkdir command</span></span><br><span class="line">                <span class="comment">// ...</span></span><br><span class="line">            	executeMkdir(tokens);</span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">            <span class="keyword">case</span> <span class="string">&quot;rmdir&quot;</span>:</span><br><span class="line">                <span class="comment">// Handle rmdir command</span></span><br><span class="line">                <span class="comment">// ...</span></span><br><span class="line">            	executeRmdir(tokens);</span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">            <span class="keyword">case</span> <span class="string">&quot;rm&quot;</span>:</span><br><span class="line">                <span class="comment">// Handle rm command</span></span><br><span class="line">                <span class="comment">// ...</span></span><br><span class="line">            	excuteRm(tokens);</span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">            <span class="keyword">case</span> <span class="string">&quot;touch&quot;</span>:</span><br><span class="line">                <span class="comment">// Handle rm command</span></span><br><span class="line">                <span class="comment">// ...</span></span><br><span class="line">            	excuteTouch(tokens);</span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">            <span class="keyword">case</span> <span class="string">&quot;chmod&quot;</span>:</span><br><span class="line">                <span class="comment">// Handle chmod command</span></span><br><span class="line">                <span class="comment">// ...</span></span><br><span class="line">            	excuteChmod(tokens);</span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">            <span class="keyword">case</span> <span class="string">&quot;cat&quot;</span>:</span><br><span class="line">                <span class="comment">// Handle cat command</span></span><br><span class="line">                <span class="comment">// ...</span></span><br><span class="line">               	excuteCat(tokens);</span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">            <span class="keyword">case</span> <span class="string">&quot;tar&quot;</span>:</span><br><span class="line">                <span class="comment">// Handle tar command</span></span><br><span class="line">                <span class="comment">// ...</span></span><br><span class="line">              	excuteTar(tokens);</span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">            <span class="keyword">case</span> <span class="string">&quot;history&quot;</span>:</span><br><span class="line">            	executeHistory();</span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">            <span class="keyword">case</span> <span class="string">&quot;pwd&quot;</span>:</span><br><span class="line">                <span class="comment">// Handle pwd command</span></span><br><span class="line">                <span class="comment">// ...</span></span><br><span class="line">            	executePwd();</span><br><span class="line">;                <span class="keyword">break</span>;</span><br><span class="line">            <span class="keyword">default</span>:</span><br><span class="line">                System.out.println(<span class="string">&quot;Command not found: &quot;</span> + commandName);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">void</span> <span class="title function_">displayCommandHistory</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">for</span> (String command : commandHistory) &#123;</span><br><span class="line">            System.out.println(command);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">    	<span class="type">minShell</span> <span class="variable">miniShell</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">minShell</span>();</span><br><span class="line">        miniShell.run();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    </span><br><span class="line">    </span><br><span class="line">    <span class="comment">// ls</span></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">void</span> <span class="title function_">executeLs</span><span class="params">(String[] tokens)</span> &#123;</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="keyword">if</span> (tokens.length == <span class="number">1</span>) &#123;</span><br><span class="line">                <span class="type">File</span> <span class="variable">currentDir</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">File</span>(System.getProperty(<span class="string">&quot;user.dir&quot;</span>));</span><br><span class="line">                String[] files = currentDir.list();</span><br><span class="line">                <span class="keyword">for</span> (String file : files) &#123;</span><br><span class="line">                    System.out.println(file);</span><br><span class="line">                &#125;</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                <span class="type">String</span> <span class="variable">option</span> <span class="operator">=</span> tokens[<span class="number">1</span>];</span><br><span class="line">                <span class="keyword">if</span> (option.equals(<span class="string">&quot;-l&quot;</span>)) &#123;</span><br><span class="line">                    <span class="type">File</span> <span class="variable">currentDir</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">File</span>(System.getProperty(<span class="string">&quot;user.dir&quot;</span>));</span><br><span class="line">                    File[] files = currentDir.listFiles();</span><br><span class="line">                    <span class="keyword">if</span> (files != <span class="literal">null</span>) &#123;</span><br><span class="line">                        <span class="keyword">for</span> (File file : files) &#123;</span><br><span class="line">                        	<span class="type">String</span> <span class="variable">permissions</span> <span class="operator">=</span> getPermissions(file);</span><br><span class="line">                        	<span class="type">String</span> <span class="variable">lastModified</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">SimpleDateFormat</span>(<span class="string">&quot;yyyy-MM-dd HH:mm:ss&quot;</span>).format(file.lastModified());</span><br><span class="line">                            System.out.println(permissions + <span class="string">&quot;\t&quot;</span> +file.length() + <span class="string">&quot;\t&quot;</span> + lastModified + <span class="string">&quot;\t&quot;</span> + file.getName());</span><br><span class="line">                        &#125;</span><br><span class="line">                    &#125;</span><br><span class="line">                &#125; <span class="keyword">else</span> <span class="keyword">if</span> (option.equals(<span class="string">&quot;-ld&quot;</span>)) &#123;</span><br><span class="line">                    <span class="type">File</span> <span class="variable">currentDir</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">File</span>(System.getProperty(<span class="string">&quot;user.dir&quot;</span>));</span><br><span class="line">                    <span class="type">String</span> <span class="variable">permissions</span> <span class="operator">=</span> getPermissions(currentDir);</span><br><span class="line">                	<span class="type">String</span> <span class="variable">lastModified</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">SimpleDateFormat</span>(<span class="string">&quot;yyyy-MM-dd HH:mm:ss&quot;</span>).format(currentDir.lastModified());</span><br><span class="line">                    System.out.println(permissions + <span class="string">&quot;\t&quot;</span> + currentDir.length() + <span class="string">&quot;\t&quot;</span> + lastModified + <span class="string">&quot;\t&quot;</span> + currentDir.getName() + <span class="string">&quot;\t&quot;</span>);</span><br><span class="line">                &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                    <span class="type">String</span> <span class="variable">path</span> <span class="operator">=</span> tokens[<span class="number">1</span>];</span><br><span class="line">                    <span class="type">File</span> <span class="variable">directory</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">File</span>(path);</span><br><span class="line">                    <span class="keyword">if</span> (directory.exists() &amp;&amp; directory.isDirectory()) &#123;</span><br><span class="line">                        String[] files = directory.list();</span><br><span class="line">                        <span class="keyword">if</span> (files != <span class="literal">null</span>) &#123;</span><br><span class="line">                            <span class="keyword">for</span> (String file : files) &#123;</span><br><span class="line">                                System.out.println(file);</span><br><span class="line">                            &#125;</span><br><span class="line">                        &#125;</span><br><span class="line">                    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                        System.out.println(<span class="string">&quot;Directory not found: &quot;</span> + path);</span><br><span class="line">                    &#125;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125; <span class="keyword">catch</span> (Exception e) &#123;</span><br><span class="line">            System.out.println(<span class="string">&quot;Failed to list files: &quot;</span> + e.getMessage());</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 查看文件权限</span></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> String <span class="title function_">getPermissions</span><span class="params">(File file)</span> &#123;</span><br><span class="line">        <span class="type">StringBuilder</span> <span class="variable">permissions</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">StringBuilder</span>();</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 判断文件类型</span></span><br><span class="line">        <span class="keyword">if</span> (file.isDirectory()) &#123;</span><br><span class="line">            permissions.append(<span class="string">&quot;d&quot;</span>);</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            permissions.append(<span class="string">&quot;-&quot;</span>);</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 判断文件权限</span></span><br><span class="line">        permissions.append(file.canRead() ? <span class="string">&quot;r&quot;</span> : <span class="string">&quot;-&quot;</span>);</span><br><span class="line">        permissions.append(file.canWrite() ? <span class="string">&quot;w&quot;</span> : <span class="string">&quot;-&quot;</span>);</span><br><span class="line">        permissions.append(file.canExecute() ? <span class="string">&quot;x&quot;</span> : <span class="string">&quot;-&quot;</span>);</span><br><span class="line"></span><br><span class="line">        <span class="keyword">return</span> permissions.toString();</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// cd</span></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">void</span> <span class="title function_">executeCd</span><span class="params">(String[] tokens)</span> &#123;</span><br><span class="line">    	 <span class="type">File</span> <span class="variable">directory</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">File</span>(tokens[<span class="number">1</span>]);</span><br><span class="line">         <span class="keyword">if</span> (directory.exists() &amp;&amp; directory.isDirectory()) &#123;</span><br><span class="line">             System.setProperty(<span class="string">&quot;user.dir&quot;</span>, directory.getAbsolutePath());</span><br><span class="line">             System.out.println(<span class="string">&quot;当前目录已更改为：&quot;</span> + directory.getAbsolutePath());</span><br><span class="line">         &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">             System.err.println(<span class="string">&quot;目录不存在：&quot;</span> + directory.getAbsolutePath());</span><br><span class="line">         &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// mkdir</span></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">void</span> <span class="title function_">executeMkdir</span><span class="params">(String[] tokens)</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (tokens.length == <span class="number">2</span>) &#123;</span><br><span class="line">            <span class="type">String</span> <span class="variable">dirName</span> <span class="operator">=</span> tokens[<span class="number">1</span>];</span><br><span class="line">            <span class="type">File</span> <span class="variable">directory</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">File</span>(dirName);</span><br><span class="line">            <span class="keyword">if</span> (!directory.exists()) &#123;</span><br><span class="line">                <span class="keyword">if</span> (directory.mkdir()) &#123;</span><br><span class="line">                    System.out.println(<span class="string">&quot;Directory created: &quot;</span> + dirName);</span><br><span class="line">                &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                    System.out.println(<span class="string">&quot;Failed to create directory: &quot;</span> + dirName);</span><br><span class="line">                &#125;</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                System.out.println(<span class="string">&quot;Directory already exists: &quot;</span> + dirName);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            System.out.println(<span class="string">&quot;Invalid command format: mkdir &lt;directory&gt;&quot;</span>);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// rmdir</span></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">void</span> <span class="title function_">executeRmdir</span><span class="params">(String[] tokens)</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (tokens.length == <span class="number">2</span>) &#123;</span><br><span class="line">            <span class="type">String</span> <span class="variable">dirName</span> <span class="operator">=</span> tokens[<span class="number">1</span>];</span><br><span class="line">            <span class="type">File</span> <span class="variable">directory</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">File</span>(dirName);</span><br><span class="line">            <span class="keyword">if</span> (directory.exists() &amp;&amp; directory.isDirectory()) &#123;</span><br><span class="line">                <span class="keyword">if</span> (directory.delete()) &#123;</span><br><span class="line">                    System.out.println(<span class="string">&quot;Directory deleted: &quot;</span> + dirName);</span><br><span class="line">                &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                    System.out.println(<span class="string">&quot;Failed to delete directory: &quot;</span> + dirName);</span><br><span class="line">                &#125;</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                System.out.println(<span class="string">&quot;Directory not found: &quot;</span> + dirName);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            System.out.println(<span class="string">&quot;Invalid command format: rmdir &lt;directory&gt;&quot;</span>);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// touch</span></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">void</span> <span class="title function_">excuteTouch</span><span class="params">(String[] tokens)</span> &#123;</span><br><span class="line">    	 <span class="type">String</span> <span class="variable">targetPath</span> <span class="operator">=</span> tokens[<span class="number">1</span>];</span><br><span class="line">    	 <span class="type">boolean</span> <span class="variable">success</span> <span class="operator">=</span> touchFile(targetPath);</span><br><span class="line"></span><br><span class="line">         <span class="keyword">if</span> (success) &#123;</span><br><span class="line">             System.out.println(<span class="string">&quot;Successfully created: &quot;</span> + targetPath);</span><br><span class="line">         &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">             System.out.println(<span class="string">&quot;Failed to create: &quot;</span> + targetPath);</span><br><span class="line">         &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> <span class="type">boolean</span> <span class="title function_">touchFile</span><span class="params">(String filePath)</span> &#123;</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="type">Path</span> <span class="variable">path</span> <span class="operator">=</span> Path.of(filePath);</span><br><span class="line">            <span class="keyword">if</span> (Files.exists(path)) &#123;</span><br><span class="line">                <span class="comment">// 文件已存在，更新访问时间和修改时间</span></span><br><span class="line">            	 <span class="type">BasicFileAttributeView</span> <span class="variable">attributes</span> <span class="operator">=</span> Files.getFileAttributeView(path, BasicFileAttributeView.class);</span><br><span class="line">                 <span class="type">FileTime</span> <span class="variable">currentTime</span> <span class="operator">=</span> FileTime.from(Instant.now());</span><br><span class="line">                 attributes.setTimes(currentTime, <span class="literal">null</span>, <span class="literal">null</span>);</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                <span class="comment">// 文件不存在，创建文件</span></span><br><span class="line">                Files.createFile(path);</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">        &#125; <span class="keyword">catch</span> (Exception e) &#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// rm</span></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">void</span> <span class="title function_">excuteRm</span><span class="params">(String[] tokens)</span>&#123;</span><br><span class="line">    	 <span class="type">String</span> <span class="variable">targetPath</span> <span class="operator">=</span> tokens[<span class="number">1</span>];</span><br><span class="line">    	 <span class="type">boolean</span> <span class="variable">success</span> <span class="operator">=</span> deleteRecursively(<span class="keyword">new</span> <span class="title class_">File</span>(targetPath));</span><br><span class="line">         <span class="keyword">if</span> (success) &#123;</span><br><span class="line">             System.out.println(<span class="string">&quot;Successfully deleted: &quot;</span> + targetPath);</span><br><span class="line">         &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">             System.out.println(<span class="string">&quot;Failed to delete: &quot;</span> + targetPath);</span><br><span class="line">         &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 递归删除子文件</span></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> <span class="type">boolean</span> <span class="title function_">deleteRecursively</span><span class="params">(File file)</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (!file.exists()) &#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">// 若是文件将递归删除子文件</span></span><br><span class="line">        <span class="keyword">if</span> (file.isDirectory()) &#123;</span><br><span class="line">            File[] files = file.listFiles();</span><br><span class="line">            <span class="keyword">if</span> (files != <span class="literal">null</span>) &#123;</span><br><span class="line">                <span class="keyword">for</span> (File child : files) &#123;</span><br><span class="line">                    <span class="type">boolean</span> <span class="variable">success</span> <span class="operator">=</span> deleteRecursively(child);</span><br><span class="line">                    <span class="keyword">if</span> (!success) &#123;</span><br><span class="line">                        <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">                    &#125;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> file.delete();</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    </span><br><span class="line">    <span class="comment">// tar</span></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">void</span> <span class="title function_">excuteTar</span><span class="params">(String[] tokens)</span> &#123;</span><br><span class="line"></span><br><span class="line">    	 <span class="keyword">try</span> &#123;</span><br><span class="line">             <span class="type">ProcessBuilder</span> <span class="variable">processBuilder</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ProcessBuilder</span>(tokens);</span><br><span class="line">             <span class="type">Process</span> <span class="variable">process</span> <span class="operator">=</span> processBuilder.start();</span><br><span class="line">            </span><br><span class="line">             <span class="type">int</span> <span class="variable">exitCode</span> <span class="operator">=</span> process.waitFor();</span><br><span class="line">             System.out.println(<span class="string">&quot;命令执行成功&quot;</span>);</span><br><span class="line">         &#125; <span class="keyword">catch</span> (IOException | InterruptedException e) &#123;</span><br><span class="line">             e.printStackTrace();</span><br><span class="line">         &#125;    </span><br><span class="line">   	</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// history</span></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">void</span> <span class="title function_">executeHistory</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; commandHistory.size(); i++) &#123;</span><br><span class="line">            System.out.println(i + <span class="number">1</span> + <span class="string">&quot;. &quot;</span> + commandHistory.get(i));</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// pwd</span></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">void</span> <span class="title function_">executePwd</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(System.getProperty(<span class="string">&quot;user.dir&quot;</span>));</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// chmod</span></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">void</span> <span class="title function_">excuteChmod</span><span class="params">(String[] tokens)</span> &#123;</span><br><span class="line">    	 <span class="type">String</span> <span class="variable">filePath</span> <span class="operator">=</span> tokens[<span class="number">2</span>]; <span class="comment">// 要更改权限的文件路径</span></span><br><span class="line">         <span class="type">String</span> <span class="variable">permissions</span> <span class="operator">=</span> tokens[<span class="number">1</span>]; <span class="comment">// 要设置的权限</span></span><br><span class="line">    	</span><br><span class="line">    	 <span class="type">boolean</span> <span class="variable">success</span> <span class="operator">=</span> changePermissions(filePath, permissions);</span><br><span class="line"></span><br><span class="line">         <span class="keyword">if</span> (success) &#123;</span><br><span class="line">             System.out.println(<span class="string">&quot;Successfully changed permissions for: &quot;</span> + filePath);</span><br><span class="line">         &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">             System.out.println(<span class="string">&quot;Failed to change permissions for: &quot;</span> + filePath);</span><br><span class="line">         &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 更改文件权限，目前仅支持数字</span></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> <span class="type">boolean</span> <span class="title function_">changePermissions</span><span class="params">(String filePath, String mode)</span> &#123;</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="type">Path</span> <span class="variable">path</span> <span class="operator">=</span> Path.of(filePath);</span><br><span class="line">            <span class="keyword">if</span> (Files.exists(path)) &#123;</span><br><span class="line">                <span class="type">File</span> <span class="variable">file</span> <span class="operator">=</span> path.toFile();</span><br><span class="line">                <span class="type">int</span> <span class="variable">permission</span> <span class="operator">=</span> Integer.parseInt(mode, <span class="number">8</span>); <span class="comment">// 将八进制字符串转换为十进制权限值</span></span><br><span class="line"></span><br><span class="line">                <span class="keyword">if</span> (file.setReadable((permission &amp; <span class="number">0400</span>) != <span class="number">0</span>, <span class="literal">false</span>) &amp;&amp;</span><br><span class="line">                    file.setWritable((permission &amp; <span class="number">0200</span>) != <span class="number">0</span>, <span class="literal">false</span>) &amp;&amp;</span><br><span class="line">                    file.setExecutable((permission &amp; <span class="number">0100</span>) != <span class="number">0</span>, <span class="literal">false</span>)) &#123;</span><br><span class="line">                    <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                System.out.println(<span class="string">&quot;File not found: &quot;</span> + filePath);</span><br><span class="line">                <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">            <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">        &#125; <span class="keyword">catch</span> (Exception e) &#123;</span><br><span class="line">            System.out.println(<span class="string">&quot;Failed to change permissions: &quot;</span> + e.getMessage());</span><br><span class="line">            <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// cat</span></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">void</span> <span class="title function_">excuteCat</span><span class="params">(String[] tokens)</span> &#123;</span><br><span class="line">    	 <span class="type">String</span> <span class="variable">filePath</span> <span class="operator">=</span> tokens[<span class="number">1</span>]; <span class="comment">// 要读取的文件路径</span></span><br><span class="line"></span><br><span class="line">         <span class="keyword">try</span> &#123;</span><br><span class="line">             <span class="type">String</span> <span class="variable">content</span> <span class="operator">=</span> readFile(filePath);</span><br><span class="line">             System.out.println(content);</span><br><span class="line">         &#125; <span class="keyword">catch</span> (IOException e) &#123;</span><br><span class="line">             System.out.println(<span class="string">&quot;Failed to read file: &quot;</span> + filePath);</span><br><span class="line">         &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> String <span class="title function_">readFile</span><span class="params">(String filePath)</span> <span class="keyword">throws</span> IOException &#123;</span><br><span class="line">        <span class="type">Path</span> <span class="variable">path</span> <span class="operator">=</span> Path.of(filePath);</span><br><span class="line">        <span class="type">byte</span>[] bytes = Files.readAllBytes(path);</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">String</span>(bytes);</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<h2 id="C版本"><a href="#C版本" class="headerlink" title="C版本"></a>C版本</h2><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br><span class="line">220</span><br><span class="line">221</span><br><span class="line">222</span><br><span class="line">223</span><br><span class="line">224</span><br><span class="line">225</span><br><span class="line">226</span><br><span class="line">227</span><br><span class="line">228</span><br><span class="line">229</span><br><span class="line">230</span><br><span class="line">231</span><br><span class="line">232</span><br><span class="line">233</span><br><span class="line">234</span><br><span class="line">235</span><br><span class="line">236</span><br><span class="line">237</span><br><span class="line">238</span><br><span class="line">239</span><br><span class="line">240</span><br><span class="line">241</span><br><span class="line">242</span><br><span class="line">243</span><br><span class="line">244</span><br><span class="line">245</span><br><span class="line">246</span><br><span class="line">247</span><br><span class="line">248</span><br><span class="line">249</span><br><span class="line">250</span><br><span class="line">251</span><br><span class="line">252</span><br><span class="line">253</span><br><span class="line">254</span><br><span class="line">255</span><br><span class="line">256</span><br><span class="line">257</span><br><span class="line">258</span><br><span class="line">259</span><br><span class="line">260</span><br><span class="line">261</span><br><span class="line">262</span><br><span class="line">263</span><br><span class="line">264</span><br><span class="line">265</span><br><span class="line">266</span><br><span class="line">267</span><br><span class="line">268</span><br><span class="line">269</span><br><span class="line">270</span><br><span class="line">271</span><br><span class="line">272</span><br><span class="line">273</span><br><span class="line">274</span><br><span class="line">275</span><br><span class="line">276</span><br><span class="line">277</span><br><span class="line">278</span><br><span class="line">279</span><br><span class="line">280</span><br><span class="line">281</span><br><span class="line">282</span><br><span class="line">283</span><br><span class="line">284</span><br><span class="line">285</span><br><span class="line">286</span><br><span class="line">287</span><br><span class="line">288</span><br><span class="line">289</span><br><span class="line">290</span><br><span class="line">291</span><br><span class="line">292</span><br><span class="line">293</span><br><span class="line">294</span><br><span class="line">295</span><br><span class="line">296</span><br><span class="line">297</span><br><span class="line">298</span><br><span class="line">299</span><br><span class="line">300</span><br><span class="line">301</span><br><span class="line">302</span><br><span class="line">303</span><br><span class="line">304</span><br><span class="line">305</span><br><span class="line">306</span><br><span class="line">307</span><br><span class="line">308</span><br><span class="line">309</span><br><span class="line">310</span><br><span class="line">311</span><br><span class="line">312</span><br><span class="line">313</span><br><span class="line">314</span><br><span class="line">315</span><br><span class="line">316</span><br><span class="line">317</span><br><span class="line">318</span><br><span class="line">319</span><br><span class="line">320</span><br><span class="line">321</span><br><span class="line">322</span><br><span class="line">323</span><br><span class="line">324</span><br><span class="line">325</span><br><span class="line">326</span><br><span class="line">327</span><br><span class="line">328</span><br><span class="line">329</span><br><span class="line">330</span><br><span class="line">331</span><br><span class="line">332</span><br><span class="line">333</span><br><span class="line">334</span><br><span class="line">335</span><br><span class="line">336</span><br><span class="line">337</span><br><span class="line">338</span><br><span class="line">339</span><br><span class="line">340</span><br><span class="line">341</span><br><span class="line">342</span><br><span class="line">343</span><br><span class="line">344</span><br><span class="line">345</span><br><span class="line">346</span><br><span class="line">347</span><br><span class="line">348</span><br><span class="line">349</span><br><span class="line">350</span><br><span class="line">351</span><br><span class="line">352</span><br><span class="line">353</span><br><span class="line">354</span><br><span class="line">355</span><br><span class="line">356</span><br><span class="line">357</span><br><span class="line">358</span><br><span class="line">359</span><br><span class="line">360</span><br><span class="line">361</span><br><span class="line">362</span><br><span class="line">363</span><br><span class="line">364</span><br><span class="line">365</span><br><span class="line">366</span><br><span class="line">367</span><br><span class="line">368</span><br><span class="line">369</span><br><span class="line">370</span><br><span class="line">371</span><br><span class="line">372</span><br><span class="line">373</span><br><span class="line">374</span><br><span class="line">375</span><br><span class="line">376</span><br><span class="line">377</span><br><span class="line">378</span><br><span class="line">379</span><br><span class="line">380</span><br><span class="line">381</span><br><span class="line">382</span><br><span class="line">383</span><br><span class="line">384</span><br><span class="line">385</span><br><span class="line">386</span><br><span class="line">387</span><br><span class="line">388</span><br><span class="line">389</span><br><span class="line">390</span><br><span class="line">391</span><br><span class="line">392</span><br><span class="line">393</span><br><span class="line">394</span><br><span class="line">395</span><br><span class="line">396</span><br><span class="line">397</span><br><span class="line">398</span><br><span class="line">399</span><br><span class="line">400</span><br><span class="line">401</span><br><span class="line">402</span><br><span class="line">403</span><br><span class="line">404</span><br><span class="line">405</span><br><span class="line">406</span><br><span class="line">407</span><br><span class="line">408</span><br><span class="line">409</span><br><span class="line">410</span><br><span class="line">411</span><br><span class="line">412</span><br><span class="line">413</span><br><span class="line">414</span><br><span class="line">415</span><br><span class="line">416</span><br><span class="line">417</span><br><span class="line">418</span><br><span class="line">419</span><br><span class="line">420</span><br><span class="line">421</span><br><span class="line">422</span><br><span class="line">423</span><br><span class="line">424</span><br><span class="line">425</span><br><span class="line">426</span><br><span class="line">427</span><br><span class="line">428</span><br><span class="line">429</span><br><span class="line">430</span><br><span class="line">431</span><br><span class="line">432</span><br><span class="line">433</span><br><span class="line">434</span><br><span class="line">435</span><br><span class="line">436</span><br><span class="line">437</span><br><span class="line">438</span><br><span class="line">439</span><br><span class="line">440</span><br><span class="line">441</span><br><span class="line">442</span><br><span class="line">443</span><br><span class="line">444</span><br><span class="line">445</span><br><span class="line">446</span><br><span class="line">447</span><br><span class="line">448</span><br><span class="line">449</span><br><span class="line">450</span><br><span class="line">451</span><br><span class="line">452</span><br><span class="line">453</span><br><span class="line">454</span><br><span class="line">455</span><br><span class="line">456</span><br><span class="line">457</span><br><span class="line">458</span><br><span class="line">459</span><br><span class="line">460</span><br><span class="line">461</span><br><span class="line">462</span><br><span class="line">463</span><br><span class="line">464</span><br><span class="line">465</span><br><span class="line">466</span><br><span class="line">467</span><br><span class="line">468</span><br><span class="line">469</span><br><span class="line">470</span><br><span class="line">471</span><br><span class="line">472</span><br><span class="line">473</span><br><span class="line">474</span><br><span class="line">475</span><br><span class="line">476</span><br><span class="line">477</span><br><span class="line">478</span><br><span class="line">479</span><br><span class="line">480</span><br><span class="line">481</span><br><span class="line">482</span><br><span class="line">483</span><br><span class="line">484</span><br><span class="line">485</span><br><span class="line">486</span><br><span class="line">487</span><br><span class="line">488</span><br><span class="line">489</span><br><span class="line">490</span><br><span class="line">491</span><br><span class="line">492</span><br><span class="line">493</span><br><span class="line">494</span><br><span class="line">495</span><br><span class="line">496</span><br><span class="line">497</span><br><span class="line">498</span><br><span class="line">499</span><br><span class="line">500</span><br><span class="line">501</span><br><span class="line">502</span><br><span class="line">503</span><br><span class="line">504</span><br><span class="line">505</span><br><span class="line">506</span><br><span class="line">507</span><br><span class="line">508</span><br><span class="line">509</span><br><span class="line">510</span><br><span class="line">511</span><br><span class="line">512</span><br><span class="line">513</span><br><span class="line">514</span><br><span class="line">515</span><br><span class="line">516</span><br><span class="line">517</span><br><span class="line">518</span><br><span class="line">519</span><br><span class="line">520</span><br><span class="line">521</span><br><span class="line">522</span><br><span class="line">523</span><br><span class="line">524</span><br><span class="line">525</span><br><span class="line">526</span><br><span class="line">527</span><br><span class="line">528</span><br><span class="line">529</span><br><span class="line">530</span><br><span class="line">531</span><br><span class="line">532</span><br><span class="line">533</span><br><span class="line">534</span><br><span class="line">535</span><br><span class="line">536</span><br><span class="line">537</span><br><span class="line">538</span><br><span class="line">539</span><br><span class="line">540</span><br><span class="line">541</span><br><span class="line">542</span><br><span class="line">543</span><br><span class="line">544</span><br><span class="line">545</span><br><span class="line">546</span><br><span class="line">547</span><br><span class="line">548</span><br><span class="line">549</span><br><span class="line">550</span><br><span class="line">551</span><br><span class="line">552</span><br><span class="line">553</span><br><span class="line">554</span><br><span class="line">555</span><br><span class="line">556</span><br><span class="line">557</span><br><span class="line">558</span><br><span class="line">559</span><br><span class="line">560</span><br><span class="line">561</span><br><span class="line">562</span><br><span class="line">563</span><br><span class="line">564</span><br><span class="line">565</span><br><span class="line">566</span><br><span class="line">567</span><br><span class="line">568</span><br><span class="line">569</span><br><span class="line">570</span><br><span class="line">571</span><br><span class="line">572</span><br><span class="line">573</span><br><span class="line">574</span><br><span class="line">575</span><br><span class="line">576</span><br><span class="line">577</span><br><span class="line">578</span><br><span class="line">579</span><br><span class="line">580</span><br><span class="line">581</span><br><span class="line">582</span><br><span class="line">583</span><br><span class="line">584</span><br><span class="line">585</span><br><span class="line">586</span><br><span class="line">587</span><br><span class="line">588</span><br><span class="line">589</span><br><span class="line">590</span><br><span class="line">591</span><br><span class="line">592</span><br><span class="line">593</span><br><span class="line">594</span><br><span class="line">595</span><br><span class="line">596</span><br><span class="line">597</span><br><span class="line">598</span><br><span class="line">599</span><br><span class="line">600</span><br><span class="line">601</span><br><span class="line">602</span><br><span class="line">603</span><br><span class="line">604</span><br><span class="line">605</span><br><span class="line">606</span><br><span class="line">607</span><br><span class="line">608</span><br><span class="line">609</span><br><span class="line">610</span><br><span class="line">611</span><br><span class="line">612</span><br><span class="line">613</span><br><span class="line">614</span><br><span class="line">615</span><br><span class="line">616</span><br><span class="line">617</span><br><span class="line">618</span><br><span class="line">619</span><br><span class="line">620</span><br><span class="line">621</span><br><span class="line">622</span><br><span class="line">623</span><br><span class="line">624</span><br><span class="line">625</span><br><span class="line">626</span><br><span class="line">627</span><br><span class="line">628</span><br><span class="line">629</span><br><span class="line">630</span><br><span class="line">631</span><br><span class="line">632</span><br><span class="line">633</span><br><span class="line">634</span><br><span class="line">635</span><br><span class="line">636</span><br><span class="line">637</span><br><span class="line">638</span><br><span class="line">639</span><br><span class="line">640</span><br><span class="line">641</span><br><span class="line">642</span><br><span class="line">643</span><br><span class="line">644</span><br><span class="line">645</span><br><span class="line">646</span><br><span class="line">647</span><br><span class="line">648</span><br><span class="line">649</span><br><span class="line">650</span><br><span class="line">651</span><br><span class="line">652</span><br><span class="line">653</span><br><span class="line">654</span><br><span class="line">655</span><br><span class="line">656</span><br><span class="line">657</span><br><span class="line">658</span><br><span class="line">659</span><br><span class="line">660</span><br><span class="line">661</span><br><span class="line">662</span><br><span class="line">663</span><br><span class="line">664</span><br><span class="line">665</span><br><span class="line">666</span><br><span class="line">667</span><br><span class="line">668</span><br><span class="line">669</span><br><span class="line">670</span><br><span class="line">671</span><br><span class="line">672</span><br><span class="line">673</span><br><span class="line">674</span><br><span class="line">675</span><br><span class="line">676</span><br><span class="line">677</span><br><span class="line">678</span><br><span class="line">679</span><br><span class="line">680</span><br><span class="line">681</span><br><span class="line">682</span><br><span class="line">683</span><br><span class="line">684</span><br><span class="line">685</span><br><span class="line">686</span><br><span class="line">687</span><br><span class="line">688</span><br><span class="line">689</span><br><span class="line">690</span><br><span class="line">691</span><br><span class="line">692</span><br><span class="line">693</span><br><span class="line">694</span><br><span class="line">695</span><br><span class="line">696</span><br><span class="line">697</span><br><span class="line">698</span><br><span class="line">699</span><br><span class="line">700</span><br><span class="line">701</span><br><span class="line">702</span><br><span class="line">703</span><br><span class="line">704</span><br><span class="line">705</span><br><span class="line">706</span><br><span class="line">707</span><br><span class="line">708</span><br><span class="line">709</span><br><span class="line">710</span><br><span class="line">711</span><br><span class="line">712</span><br><span class="line">713</span><br><span class="line">714</span><br><span class="line">715</span><br><span class="line">716</span><br><span class="line">717</span><br><span class="line">718</span><br><span class="line">719</span><br><span class="line">720</span><br><span class="line">721</span><br><span class="line">722</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* 头文件 */</span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;unistd.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;sys/wait.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;stdio.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;stdlib.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;ctype.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;string.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;sys/stat.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;fcntl.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;signal.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;sys/stat.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;dirent.h&gt;</span>             <span class="comment">// readdir函数</span></span></span><br><span class="line"></span><br><span class="line"><span class="comment">/* 宏定义 */</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> IN 1</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> OUT 0</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> MAX_CMD 10</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> BUFFSIZE 100</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> MAX_CMD_LEN 100</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">/* 全局变量 */</span></span><br><span class="line"><span class="type">int</span> argc;                                       <span class="comment">// 有效参数个数</span></span><br><span class="line"><span class="type">char</span>* argv[MAX_CMD];                            <span class="comment">// 参数数组</span></span><br><span class="line"><span class="type">char</span> command[MAX_CMD][MAX_CMD_LEN];             <span class="comment">// 参数数组</span></span><br><span class="line"><span class="type">char</span> buf[BUFFSIZE];                             <span class="comment">// 接受输入的参数数组</span></span><br><span class="line"><span class="type">char</span> backupBuf[BUFFSIZE];                       <span class="comment">// 参数数组的备份</span></span><br><span class="line"><span class="type">char</span> curPath[BUFFSIZE];                         <span class="comment">// 当前shell工作路径</span></span><br><span class="line"><span class="type">int</span> i, j;                                       <span class="comment">// 循环变量</span></span><br><span class="line"><span class="type">int</span> commandNum;                                 <span class="comment">// 已经输入指令数目</span></span><br><span class="line"><span class="type">char</span> history[MAX_CMD][BUFFSIZE];                <span class="comment">// 存放历史命令</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="type">int</span> <span class="title function_">get_input</span><span class="params">(<span class="type">char</span> buf[])</span>;                      <span class="comment">// 输入指令并存入buf数组</span></span><br><span class="line"><span class="type">void</span> <span class="title function_">parse</span><span class="params">(<span class="type">char</span>* buf)</span>;                          <span class="comment">// 解析字符串</span></span><br><span class="line"><span class="type">void</span> <span class="title function_">do_cmd</span><span class="params">(<span class="type">int</span> argc, <span class="type">char</span>* argv[])</span>;</span><br><span class="line">    <span class="type">int</span> <span class="title function_">callCd</span><span class="params">(<span class="type">int</span> argc)</span>;                       <span class="comment">// 执行cd指令</span></span><br><span class="line">    <span class="type">int</span> <span class="title function_">printHistory</span><span class="params">(<span class="type">char</span> command[MAX_CMD][MAX_CMD_LEN])</span>;   <span class="comment">// 打印历史指令</span></span><br><span class="line">    <span class="comment">// 重定向指令</span></span><br><span class="line">    <span class="type">int</span> <span class="title function_">commandWithOutputRedi</span><span class="params">(<span class="type">char</span> buf[BUFFSIZE])</span>;          <span class="comment">// 执行输出重定向</span></span><br><span class="line">    <span class="type">int</span> <span class="title function_">commandWithInputRedi</span><span class="params">(<span class="type">char</span> buf[BUFFSIZE])</span>;           <span class="comment">// 执行输入重定向命令</span></span><br><span class="line">    <span class="type">int</span> <span class="title function_">commandWithReOutputRedi</span><span class="params">(<span class="type">char</span> buf[BUFFSIZE])</span>;        <span class="comment">// 执行输出重定向追加写</span></span><br><span class="line">    <span class="type">int</span> <span class="title function_">commandWithPipe</span><span class="params">(<span class="type">char</span> buf[BUFFSIZE])</span>;                <span class="comment">// 执行管道命令</span></span><br><span class="line">    <span class="type">int</span> <span class="title function_">commandInBackground</span><span class="params">(<span class="type">char</span> buf[BUFFSIZE])</span>;</span><br><span class="line">    <span class="type">void</span> <span class="title function_">myTop</span><span class="params">()</span>;                                           <span class="comment">// 执行mytop指令</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">/* 函数定义 */</span></span><br><span class="line"><span class="comment">/* get_input接受输入的字符并存入buf数组中 */</span></span><br><span class="line"><span class="type">int</span> <span class="title function_">get_input</span><span class="params">(<span class="type">char</span> buf[])</span> &#123;</span><br><span class="line">    <span class="comment">// buf数组初始化</span></span><br><span class="line">    <span class="built_in">memset</span>(buf, <span class="number">0x00</span>, BUFFSIZE);</span><br><span class="line">    <span class="built_in">memset</span>(backupBuf, <span class="number">0x00</span>, BUFFSIZE);        </span><br><span class="line"></span><br><span class="line">    fgets(buf, BUFFSIZE, <span class="built_in">stdin</span>);</span><br><span class="line">    <span class="comment">// 去除fgets带来的末尾\n字符</span></span><br><span class="line">    buf[<span class="built_in">strlen</span>(buf) - <span class="number">1</span>] = <span class="string">&#x27;\0&#x27;</span>;</span><br><span class="line">    <span class="keyword">return</span> <span class="built_in">strlen</span>(buf);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="type">void</span> <span class="title function_">parse</span><span class="params">(<span class="type">char</span>* buf)</span> &#123;</span><br><span class="line">    <span class="comment">// 初始化argv数组和argc</span></span><br><span class="line">    <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; MAX_CMD; i++) &#123;</span><br><span class="line">        argv[i] = <span class="literal">NULL</span>;</span><br><span class="line">        <span class="keyword">for</span> (j = <span class="number">0</span>; j &lt; MAX_CMD_LEN; j++)</span><br><span class="line">            command[i][j] = <span class="string">&#x27;\0&#x27;</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    argc = <span class="number">0</span>;</span><br><span class="line">    <span class="comment">// 下列操作改变了buf数组, 为buf数组做个备份</span></span><br><span class="line">    <span class="built_in">strcpy</span>(backupBuf, buf);</span><br><span class="line">    <span class="comment">/** 构建command数组</span></span><br><span class="line"><span class="comment">     *  即若输入为&quot;ls -a&quot;</span></span><br><span class="line"><span class="comment">     *  strcmp(command[0], &quot;ls&quot;) == 0 成立且</span></span><br><span class="line"><span class="comment">     *  strcmp(command[1], &quot;-a&quot;) == 0 成立</span></span><br><span class="line"><span class="comment">     */</span>  </span><br><span class="line">    <span class="type">int</span> len = <span class="built_in">strlen</span>(buf);</span><br><span class="line">    <span class="keyword">for</span> (i = <span class="number">0</span>, j = <span class="number">0</span>; i &lt; len; ++i) &#123;</span><br><span class="line">        <span class="keyword">if</span> (buf[i] != <span class="string">&#x27; &#x27;</span>) &#123;</span><br><span class="line">            command[argc][j++] = buf[i];</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            <span class="keyword">if</span> (j != <span class="number">0</span>) &#123;</span><br><span class="line">                command[argc][j] = <span class="string">&#x27;\0&#x27;</span>;</span><br><span class="line">                ++argc;</span><br><span class="line">                j = <span class="number">0</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (j != <span class="number">0</span>) &#123;</span><br><span class="line">        command[argc][j] = <span class="string">&#x27;\0&#x27;</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/** 构建argv数组</span></span><br><span class="line"><span class="comment">     *  即若输入buf为&quot;ls -a&quot;</span></span><br><span class="line"><span class="comment">     *  strcmp(argv[0], &quot;ls&quot;) == 0 成立且</span></span><br><span class="line"><span class="comment">     *  strcmp(argv[1], &quot;-a&quot;) == 0 成立*/</span></span><br><span class="line">    argc = <span class="number">0</span>;</span><br><span class="line">    <span class="type">int</span> flg = OUT;</span><br><span class="line">    <span class="keyword">for</span> (i = <span class="number">0</span>; buf[i] != <span class="string">&#x27;\0&#x27;</span>; i++) &#123;</span><br><span class="line">        <span class="keyword">if</span> (flg == OUT &amp;&amp; !<span class="built_in">isspace</span>(buf[i])) &#123;</span><br><span class="line">            flg = IN;</span><br><span class="line">            argv[argc++] = buf + i;</span><br><span class="line">        &#125; <span class="keyword">else</span> <span class="keyword">if</span> (flg == IN &amp;&amp; <span class="built_in">isspace</span>(buf[i])) &#123;</span><br><span class="line">            flg = OUT;</span><br><span class="line">            buf[i] = <span class="string">&#x27;\0&#x27;</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    argv[argc] = <span class="literal">NULL</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="type">void</span> <span class="title function_">do_cmd</span><span class="params">(<span class="type">int</span> argc, <span class="type">char</span>* argv[])</span> &#123;</span><br><span class="line">    <span class="type">pid_t</span> pid;</span><br><span class="line">    <span class="comment">/* 识别program命令 */</span></span><br><span class="line">    <span class="comment">// 识别重定向输出命令</span></span><br><span class="line">    <span class="keyword">for</span> (j = <span class="number">0</span>; j &lt; MAX_CMD; j++) &#123;</span><br><span class="line">        <span class="keyword">if</span> (<span class="built_in">strcmp</span>(command[j], <span class="string">&quot;&gt;&quot;</span>) == <span class="number">0</span>) &#123;</span><br><span class="line">            <span class="built_in">strcpy</span>(buf, backupBuf);</span><br><span class="line">            <span class="type">int</span> sample = commandWithOutputRedi(buf);</span><br><span class="line">            <span class="keyword">return</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">// 识别输入重定向</span></span><br><span class="line">    <span class="keyword">for</span> (j = <span class="number">0</span>; j &lt; MAX_CMD; j++) &#123;</span><br><span class="line">        <span class="keyword">if</span> (<span class="built_in">strcmp</span>(command[i], <span class="string">&quot;&lt;&quot;</span>) == <span class="number">0</span>) &#123;</span><br><span class="line">            <span class="built_in">strcpy</span>(buf, backupBuf);</span><br><span class="line">            <span class="type">int</span> sample = commandWithInputRedi(buf);</span><br><span class="line">            <span class="keyword">return</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">// 识别追加写重定向</span></span><br><span class="line">    <span class="keyword">for</span> (j = <span class="number">0</span>; j &lt; MAX_CMD; j++) &#123;</span><br><span class="line">        <span class="keyword">if</span> (<span class="built_in">strcmp</span>(command[j], <span class="string">&quot;&gt;&gt;&quot;</span>) == <span class="number">0</span>) &#123;</span><br><span class="line">            <span class="built_in">strcpy</span>(buf, backupBuf);</span><br><span class="line">            <span class="type">int</span> sample = commandWithReOutputRedi(buf);</span><br><span class="line">            <span class="keyword">return</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 识别管道命令</span></span><br><span class="line">    <span class="keyword">for</span> (j = <span class="number">0</span>; j &lt; MAX_CMD; j++) &#123;</span><br><span class="line">        <span class="keyword">if</span> (<span class="built_in">strcmp</span>(command[j], <span class="string">&quot;|&quot;</span>) == <span class="number">0</span>) &#123;</span><br><span class="line">            <span class="built_in">strcpy</span>(buf, backupBuf);</span><br><span class="line">            <span class="type">int</span> sample = commandWithPipe(buf);</span><br><span class="line">            <span class="keyword">return</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 识别后台运行命令</span></span><br><span class="line">    <span class="keyword">for</span> (j = <span class="number">0</span>; j &lt; MAX_CMD; j++) &#123;</span><br><span class="line">        <span class="keyword">if</span> (<span class="built_in">strcmp</span>(command[j], <span class="string">&quot;&amp;&quot;</span>) == <span class="number">0</span>) &#123;</span><br><span class="line">            <span class="built_in">strcpy</span>(buf, backupBuf);</span><br><span class="line">            <span class="type">int</span> sample = commandInBackground(buf);</span><br><span class="line">            <span class="keyword">return</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="comment">/* 识别shell内置命令 */</span></span><br><span class="line">    <span class="keyword">if</span> (<span class="built_in">strcmp</span>(command[<span class="number">0</span>], <span class="string">&quot;cd&quot;</span>) == <span class="number">0</span>) &#123;</span><br><span class="line">        <span class="type">int</span> res = callCd(argc);</span><br><span class="line">        <span class="keyword">if</span> (!res) <span class="built_in">printf</span>(<span class="string">&quot;cd指令输入错误!&quot;</span>);</span><br><span class="line">    &#125; <span class="keyword">else</span> <span class="keyword">if</span> (<span class="built_in">strcmp</span>(command[<span class="number">0</span>], <span class="string">&quot;history&quot;</span>) == <span class="number">0</span>) &#123;</span><br><span class="line">        printHistory(command);</span><br><span class="line">    &#125; <span class="keyword">else</span> <span class="keyword">if</span> (<span class="built_in">strcmp</span>(command[<span class="number">0</span>], <span class="string">&quot;mytop&quot;</span>) == <span class="number">0</span>) &#123;</span><br><span class="line">        myTop();</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125; <span class="keyword">else</span> <span class="keyword">if</span> (<span class="built_in">strcmp</span>(command[<span class="number">0</span>], <span class="string">&quot;exit&quot;</span>) == <span class="number">0</span>) &#123;</span><br><span class="line">        <span class="built_in">exit</span>(<span class="number">0</span>);</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        <span class="keyword">switch</span>(pid = fork()) &#123;</span><br><span class="line">            <span class="comment">// fork子进程失败</span></span><br><span class="line">            <span class="keyword">case</span> <span class="number">-1</span>:</span><br><span class="line">                <span class="built_in">printf</span>(<span class="string">&quot;创建子进程未成功&quot;</span>);</span><br><span class="line">                <span class="keyword">return</span>;</span><br><span class="line">            <span class="comment">// 处理子进程</span></span><br><span class="line">            <span class="keyword">case</span> <span class="number">0</span>:</span><br><span class="line">                &#123;   <span class="comment">/* 函数说明：execvp()会从PATH 环境变量所指的目录中查找符合参数file 的文件名, 找到后便执行该文件, </span></span><br><span class="line"><span class="comment">                     * 然后将第二个参数argv 传给该欲执行的文件。</span></span><br><span class="line"><span class="comment">                     * 返回值：如果执行成功则函数不会返回, 执行失败则直接返回-1, 失败原因存于errno 中. </span></span><br><span class="line"><span class="comment">                     * */</span></span><br><span class="line">                    execvp(argv[<span class="number">0</span>], argv);</span><br><span class="line">                    <span class="comment">// 代码健壮性: 如果子进程未被成功执行, 则报错</span></span><br><span class="line">                    <span class="built_in">printf</span>(<span class="string">&quot;%s: 命令输入错误\n&quot;</span>, argv[<span class="number">0</span>]);</span><br><span class="line">                    <span class="comment">// exit函数终止当前进程, 括号内参数为1时, 会像操作系统报告该进程因异常而终止</span></span><br><span class="line">                    <span class="built_in">exit</span>(<span class="number">1</span>);</span><br><span class="line">                &#125;</span><br><span class="line">            <span class="keyword">default</span>: &#123;</span><br><span class="line">                    <span class="type">int</span> status;</span><br><span class="line">                    waitpid(pid, &amp;status, <span class="number">0</span>);      <span class="comment">// 等待子进程返回</span></span><br><span class="line">                    <span class="type">int</span> err = WEXITSTATUS(status); <span class="comment">// 读取子进程的返回码</span></span><br><span class="line"></span><br><span class="line">                    <span class="keyword">if</span> (err) &#123; </span><br><span class="line">                        <span class="built_in">printf</span>(<span class="string">&quot;Error: %s\n&quot;</span>, strerror(err));</span><br><span class="line">                    &#125;                    </span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="type">int</span> <span class="title function_">callCd</span><span class="params">(<span class="type">int</span> argc)</span> &#123;</span><br><span class="line">    <span class="comment">// result为1代表执行成功, 为0代表执行失败</span></span><br><span class="line">    <span class="type">int</span> result = <span class="number">1</span>;</span><br><span class="line">    <span class="keyword">if</span> (argc != <span class="number">2</span>) &#123;</span><br><span class="line">        <span class="built_in">printf</span>(<span class="string">&quot;指令数目错误!&quot;</span>);</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        <span class="type">int</span> ret = chdir(command[<span class="number">1</span>]);</span><br><span class="line">        <span class="keyword">if</span> (ret) <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (result) &#123;</span><br><span class="line">        <span class="type">char</span>* res = getcwd(curPath, BUFFSIZE);</span><br><span class="line">        <span class="keyword">if</span> (res == <span class="literal">NULL</span>) &#123;</span><br><span class="line">            <span class="built_in">printf</span>(<span class="string">&quot;文件路径不存在!&quot;</span>);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> result;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="type">int</span> <span class="title function_">printHistory</span><span class="params">(<span class="type">char</span> command[MAX_CMD][MAX_CMD_LEN])</span> &#123;</span><br><span class="line">    <span class="type">int</span> n = atoi(command[<span class="number">1</span>]);</span><br><span class="line"></span><br><span class="line">    <span class="keyword">for</span> (i = n; i &gt; <span class="number">0</span> &amp;&amp; commandNum - i &gt;= <span class="number">0</span>; i--) &#123;</span><br><span class="line">        <span class="built_in">printf</span>(<span class="string">&quot;%d\t%s\n&quot;</span>, n - i + <span class="number">1</span>, history[commandNum - i]);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="type">int</span> <span class="title function_">commandWithOutputRedi</span><span class="params">(<span class="type">char</span> buf[BUFFSIZE])</span> &#123;</span><br><span class="line">    <span class="built_in">strcpy</span>(buf, backupBuf);</span><br><span class="line">    <span class="type">char</span> outFile[BUFFSIZE];</span><br><span class="line">    <span class="built_in">memset</span>(outFile, <span class="number">0x00</span>, BUFFSIZE);</span><br><span class="line">    <span class="type">int</span> RediNum = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">for</span> ( i = <span class="number">0</span>; i + <span class="number">1</span> &lt; <span class="built_in">strlen</span>(buf); i++) &#123;</span><br><span class="line">        <span class="keyword">if</span> (buf[i] == <span class="string">&#x27;&gt;&#x27;</span> &amp;&amp; buf[i + <span class="number">1</span>] == <span class="string">&#x27; &#x27;</span>) &#123;</span><br><span class="line">            RediNum++;</span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (RediNum != <span class="number">1</span>) &#123;</span><br><span class="line">        <span class="built_in">printf</span>(<span class="string">&quot;输出重定向指令输入有误!&quot;</span>);</span><br><span class="line">        <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; argc; i++) &#123;</span><br><span class="line">        <span class="keyword">if</span> (<span class="built_in">strcmp</span>(command[i], <span class="string">&quot;&gt;&quot;</span>) == <span class="number">0</span>) &#123;</span><br><span class="line">            <span class="keyword">if</span> (i + <span class="number">1</span> &lt; argc) &#123;</span><br><span class="line">                <span class="built_in">strcpy</span>(outFile, command[i + <span class="number">1</span>]);</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                <span class="built_in">printf</span>(<span class="string">&quot;缺少输出文件!&quot;</span>);</span><br><span class="line">                <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 指令分割, outFile为输出文件, buf为重定向符号前的命令</span></span><br><span class="line">    <span class="keyword">for</span> (j = <span class="number">0</span>; j &lt; <span class="built_in">strlen</span>(buf); j++) &#123;</span><br><span class="line">        <span class="keyword">if</span> (buf[j] == <span class="string">&#x27;&gt;&#x27;</span>) &#123;</span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    buf[j - <span class="number">1</span>] = <span class="string">&#x27;\0&#x27;</span>;</span><br><span class="line">    buf[j] = <span class="string">&#x27;\0&#x27;</span>;</span><br><span class="line">    <span class="comment">// 解析指令</span></span><br><span class="line">    parse(buf);</span><br><span class="line">    <span class="type">pid_t</span> pid;</span><br><span class="line">    <span class="keyword">switch</span>(pid = fork()) &#123;</span><br><span class="line">        <span class="keyword">case</span> <span class="number">-1</span>: &#123;</span><br><span class="line">            <span class="built_in">printf</span>(<span class="string">&quot;创建子进程未成功&quot;</span>);</span><br><span class="line">            <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">// 处理子进程:</span></span><br><span class="line">        <span class="keyword">case</span> <span class="number">0</span>: &#123;</span><br><span class="line">            <span class="comment">// 完成输出重定向</span></span><br><span class="line">            <span class="type">int</span> fd;</span><br><span class="line">            fd = open(outFile, O_WRONLY|O_CREAT|O_TRUNC, <span class="number">7777</span>);</span><br><span class="line">            <span class="comment">// 文件打开失败</span></span><br><span class="line">            <span class="keyword">if</span> (fd &lt; <span class="number">0</span>) &#123;</span><br><span class="line">                <span class="built_in">exit</span>(<span class="number">1</span>);</span><br><span class="line">            &#125;</span><br><span class="line">            dup2(fd, STDOUT_FILENO);  </span><br><span class="line">            execvp(argv[<span class="number">0</span>], argv);</span><br><span class="line">            <span class="keyword">if</span> (fd != STDOUT_FILENO) &#123;</span><br><span class="line">                close(fd);</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="comment">// 代码健壮性: 如果子进程未被成功执行, 则报错</span></span><br><span class="line">            <span class="built_in">printf</span>(<span class="string">&quot;%s: 命令输入错误\n&quot;</span>, argv[<span class="number">0</span>]);</span><br><span class="line">            <span class="comment">// exit函数终止当前进程, 括号内参数为1时, 会像操作系统报告该进程因异常而终止</span></span><br><span class="line">            <span class="built_in">exit</span>(<span class="number">1</span>);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">default</span>: &#123;</span><br><span class="line">            <span class="type">int</span> status;</span><br><span class="line">            waitpid(pid, &amp;status, <span class="number">0</span>);       <span class="comment">// 等待子进程返回</span></span><br><span class="line">            <span class="type">int</span> err = WEXITSTATUS(status);  <span class="comment">// 读取子进程的返回码</span></span><br><span class="line">            <span class="keyword">if</span> (err) &#123; </span><br><span class="line">                <span class="built_in">printf</span>(<span class="string">&quot;Error: %s\n&quot;</span>, strerror(err));</span><br><span class="line">            &#125; </span><br><span class="line">        &#125;                        </span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="type">int</span> <span class="title function_">commandWithInputRedi</span><span class="params">(<span class="type">char</span> buf[BUFFSIZE])</span> &#123;</span><br><span class="line">    <span class="built_in">strcpy</span>(buf, backupBuf);</span><br><span class="line">    <span class="type">char</span> inFile[BUFFSIZE];</span><br><span class="line">    <span class="built_in">memset</span>(inFile, <span class="number">0x00</span>, BUFFSIZE);</span><br><span class="line">    <span class="type">int</span> RediNum = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">for</span> ( i = <span class="number">0</span>; i + <span class="number">1</span>&lt; <span class="built_in">strlen</span>(buf); i++) &#123;</span><br><span class="line">        <span class="keyword">if</span> (buf[i] == <span class="string">&#x27;&lt;&#x27;</span> &amp;&amp; buf[i + <span class="number">1</span>] == <span class="string">&#x27; &#x27;</span>) &#123;</span><br><span class="line">            RediNum++;</span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (RediNum != <span class="number">1</span>) &#123;</span><br><span class="line">        <span class="built_in">printf</span>(<span class="string">&quot;输入重定向指令输入有误!&quot;</span>);</span><br><span class="line">        <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; argc; i++) &#123;</span><br><span class="line">        <span class="keyword">if</span> (<span class="built_in">strcmp</span>(command[i], <span class="string">&quot;&lt;&quot;</span>) == <span class="number">0</span>) &#123;</span><br><span class="line">            <span class="keyword">if</span> (i + <span class="number">1</span> &lt; argc) &#123;</span><br><span class="line">                <span class="built_in">strcpy</span>(inFile, command[i + <span class="number">1</span>]);</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                <span class="built_in">printf</span>(<span class="string">&quot;缺少输入指令!&quot;</span>);</span><br><span class="line">                <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 指令分割, InFile为输出文件, buf为重定向符号前的命令</span></span><br><span class="line">    <span class="keyword">for</span> (j = <span class="number">0</span>; j &lt; <span class="built_in">strlen</span>(buf); j++) &#123;</span><br><span class="line">        <span class="keyword">if</span> (buf[j] == <span class="string">&#x27;&lt;&#x27;</span>) &#123;</span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    buf[j - <span class="number">1</span>] = <span class="string">&#x27;\0&#x27;</span>;</span><br><span class="line">    buf[j] = <span class="string">&#x27;\0&#x27;</span>;</span><br><span class="line">    parse(buf);</span><br><span class="line">    <span class="type">pid_t</span> pid;</span><br><span class="line">    <span class="keyword">switch</span>(pid = fork()) &#123;</span><br><span class="line">        <span class="keyword">case</span> <span class="number">-1</span>: &#123;</span><br><span class="line">            <span class="built_in">printf</span>(<span class="string">&quot;创建子进程未成功&quot;</span>);</span><br><span class="line">            <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">// 处理子进程:</span></span><br><span class="line">        <span class="keyword">case</span> <span class="number">0</span>: &#123;</span><br><span class="line">            <span class="comment">// 完成输入重定向</span></span><br><span class="line">            <span class="type">int</span> fd;</span><br><span class="line">            fd = open(inFile, O_RDONLY, <span class="number">7777</span>);</span><br><span class="line">            <span class="comment">// 文件打开失败</span></span><br><span class="line">            <span class="keyword">if</span> (fd &lt; <span class="number">0</span>) &#123;</span><br><span class="line">                <span class="built_in">exit</span>(<span class="number">1</span>);</span><br><span class="line">            &#125;</span><br><span class="line">            dup2(fd, STDIN_FILENO);  </span><br><span class="line">            execvp(argv[<span class="number">0</span>], argv);</span><br><span class="line">            <span class="keyword">if</span> (fd != STDIN_FILENO) &#123;</span><br><span class="line">                close(fd);</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="comment">// 代码健壮性: 如果子进程未被成功执行, 则报错</span></span><br><span class="line">            <span class="built_in">printf</span>(<span class="string">&quot;%s: 命令输入错误\n&quot;</span>, argv[<span class="number">0</span>]);</span><br><span class="line">            <span class="comment">// exit函数终止当前进程, 括号内参数为1时, 会像操作系统报告该进程因异常而终止</span></span><br><span class="line">            <span class="built_in">exit</span>(<span class="number">1</span>);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">default</span>: &#123;</span><br><span class="line">            <span class="type">int</span> status;</span><br><span class="line">            waitpid(pid, &amp;status, <span class="number">0</span>);       <span class="comment">// 等待子进程返回</span></span><br><span class="line">            <span class="type">int</span> err = WEXITSTATUS(status);  <span class="comment">// 读取子进程的返回码</span></span><br><span class="line">            <span class="keyword">if</span> (err) &#123; </span><br><span class="line">                <span class="built_in">printf</span>(<span class="string">&quot;Error: %s\n&quot;</span>, strerror(err));</span><br><span class="line">            &#125; </span><br><span class="line">        &#125;                        </span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="type">int</span> <span class="title function_">commandWithReOutputRedi</span><span class="params">(<span class="type">char</span> buf[BUFFSIZE])</span> &#123;</span><br><span class="line">    <span class="built_in">strcpy</span>(buf, backupBuf);</span><br><span class="line">    <span class="type">char</span> reOutFile[BUFFSIZE];</span><br><span class="line">    <span class="built_in">memset</span>(reOutFile, <span class="number">0x00</span>, BUFFSIZE);</span><br><span class="line">    <span class="type">int</span> RediNum = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">for</span> ( i = <span class="number">0</span>; i + <span class="number">2</span> &lt; <span class="built_in">strlen</span>(buf); i++) &#123;</span><br><span class="line">        <span class="keyword">if</span> (buf[i] == <span class="string">&#x27;&gt;&#x27;</span> &amp;&amp; buf[i + <span class="number">1</span>] == <span class="string">&#x27;&gt;&#x27;</span> &amp;&amp; buf[i + <span class="number">2</span>] == <span class="string">&#x27; &#x27;</span>) &#123;</span><br><span class="line">            RediNum++;</span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (RediNum != <span class="number">1</span>) &#123;</span><br><span class="line">        <span class="built_in">printf</span>(<span class="string">&quot;追加输出重定向指令输入有误!&quot;</span>);</span><br><span class="line">        <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; argc; i++) &#123;</span><br><span class="line">        <span class="keyword">if</span> (<span class="built_in">strcmp</span>(command[i], <span class="string">&quot;&gt;&gt;&quot;</span>) == <span class="number">0</span>) &#123;</span><br><span class="line">            <span class="keyword">if</span> (i + <span class="number">1</span> &lt; argc) &#123;</span><br><span class="line">                <span class="built_in">strcpy</span>(reOutFile, command[i + <span class="number">1</span>]);</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                <span class="built_in">printf</span>(<span class="string">&quot;缺少输出文件!&quot;</span>);</span><br><span class="line">                <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 指令分割, outFile为输出文件, buf为重定向符号前的命令</span></span><br><span class="line">    <span class="keyword">for</span> (j = <span class="number">0</span>; j + <span class="number">2</span> &lt; <span class="built_in">strlen</span>(buf); j++) &#123;</span><br><span class="line">        <span class="keyword">if</span> (buf[j] == <span class="string">&#x27;&gt;&#x27;</span> &amp;&amp; buf[j + <span class="number">1</span>] == <span class="string">&#x27;&gt;&#x27;</span> </span><br><span class="line">            &amp;&amp; buf[j + <span class="number">2</span>] == <span class="string">&#x27; &#x27;</span>) &#123;</span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    buf[j - <span class="number">1</span>] = <span class="string">&#x27;\0&#x27;</span>;</span><br><span class="line">    buf[j] = <span class="string">&#x27;\0&#x27;</span>;</span><br><span class="line">    <span class="comment">// 解析指令</span></span><br><span class="line">    parse(buf);</span><br><span class="line">    <span class="type">pid_t</span> pid;</span><br><span class="line">    <span class="keyword">switch</span>(pid = fork()) &#123;</span><br><span class="line">        <span class="keyword">case</span> <span class="number">-1</span>: &#123;</span><br><span class="line">            <span class="built_in">printf</span>(<span class="string">&quot;创建子进程未成功&quot;</span>);</span><br><span class="line">            <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">// 处理子进程:</span></span><br><span class="line">        <span class="keyword">case</span> <span class="number">0</span>: &#123;</span><br><span class="line">            <span class="comment">// 完成输出重定向</span></span><br><span class="line">            <span class="type">int</span> fd;</span><br><span class="line">            fd = open(reOutFile, O_WRONLY|O_APPEND|O_CREAT|O_APPEND, <span class="number">7777</span>);</span><br><span class="line">            <span class="comment">// 文件打开失败</span></span><br><span class="line">            <span class="keyword">if</span> (fd &lt; <span class="number">0</span>) &#123;</span><br><span class="line">                <span class="built_in">exit</span>(<span class="number">1</span>);</span><br><span class="line">            &#125;</span><br><span class="line">            dup2(fd, STDOUT_FILENO);  </span><br><span class="line">            execvp(argv[<span class="number">0</span>], argv);</span><br><span class="line">            <span class="keyword">if</span> (fd != STDOUT_FILENO) &#123;</span><br><span class="line">                close(fd);</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="comment">// 代码健壮性: 如果子进程未被成功执行, 则报错</span></span><br><span class="line">            <span class="built_in">printf</span>(<span class="string">&quot;%s: 命令输入错误\n&quot;</span>, argv[<span class="number">0</span>]);</span><br><span class="line">            <span class="comment">// exit函数终止当前进程, 括号内参数为1时, 会像操作系统报告该进程因异常而终止</span></span><br><span class="line">            <span class="built_in">exit</span>(<span class="number">1</span>);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">default</span>: &#123;</span><br><span class="line">            <span class="type">int</span> status;</span><br><span class="line">            waitpid(pid, &amp;status, <span class="number">0</span>);       <span class="comment">// 等待子进程返回</span></span><br><span class="line">            <span class="type">int</span> err = WEXITSTATUS(status);  <span class="comment">// 读取子进程的返回码</span></span><br><span class="line">            <span class="keyword">if</span> (err) &#123; </span><br><span class="line">                <span class="built_in">printf</span>(<span class="string">&quot;Error: %s\n&quot;</span>, strerror(err));</span><br><span class="line">            &#125; </span><br><span class="line">        &#125;                        </span><br><span class="line">    &#125;   </span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="type">int</span> <span class="title function_">commandWithPipe</span><span class="params">(<span class="type">char</span> buf[BUFFSIZE])</span> &#123;</span><br><span class="line">    <span class="comment">// 获取管道符号的位置索引</span></span><br><span class="line">    <span class="keyword">for</span>(j = <span class="number">0</span>; buf[j] != <span class="string">&#x27;\0&#x27;</span>; j++) &#123;</span><br><span class="line">        <span class="keyword">if</span> (buf[j] == <span class="string">&#x27;|&#x27;</span>)</span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 分离指令, 将管道符号前后的指令存放在两个数组中</span></span><br><span class="line">    <span class="comment">// outputBuf存放管道前的命令, inputBuf存放管道后的命令</span></span><br><span class="line">    <span class="type">char</span> outputBuf[j];</span><br><span class="line">    <span class="built_in">memset</span>(outputBuf, <span class="number">0x00</span>, j);</span><br><span class="line">    <span class="type">char</span> inputBuf[<span class="built_in">strlen</span>(buf) - j];</span><br><span class="line">    <span class="built_in">memset</span>(inputBuf, <span class="number">0x00</span>, <span class="built_in">strlen</span>(buf) - j);</span><br><span class="line">    <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; j - <span class="number">1</span>; i++) &#123;</span><br><span class="line">        outputBuf[i] = buf[i];</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; <span class="built_in">strlen</span>(buf) - j - <span class="number">1</span>; i++) &#123;</span><br><span class="line">        inputBuf[i] = buf[j + <span class="number">2</span> + i];</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="type">int</span> pd[<span class="number">2</span>];</span><br><span class="line">    <span class="type">pid_t</span> pid;</span><br><span class="line">    <span class="keyword">if</span> (pipe(pd) &lt; <span class="number">0</span>) &#123;</span><br><span class="line">        perror(<span class="string">&quot;pipe()&quot;</span>);</span><br><span class="line">        <span class="built_in">exit</span>(<span class="number">1</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    pid = fork();</span><br><span class="line">    <span class="keyword">if</span> (pid &lt; <span class="number">0</span>) &#123;</span><br><span class="line">        perror(<span class="string">&quot;fork()&quot;</span>);</span><br><span class="line">        <span class="built_in">exit</span>(<span class="number">1</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (pid == <span class="number">0</span>) &#123;                     <span class="comment">// 子进程写管道</span></span><br><span class="line">        close(pd[<span class="number">0</span>]);                   <span class="comment">// 关闭子进程的读端</span></span><br><span class="line">        dup2(pd[<span class="number">1</span>], STDOUT_FILENO);     <span class="comment">// 将子进程的写端作为标准输出</span></span><br><span class="line">        parse(outputBuf);</span><br><span class="line">        execvp(argv[<span class="number">0</span>], argv);</span><br><span class="line">        <span class="keyword">if</span> (pd[<span class="number">1</span>] != STDOUT_FILENO) &#123;</span><br><span class="line">            close(pd[<span class="number">1</span>]);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;<span class="keyword">else</span> &#123;                              <span class="comment">// 父进程读管道</span></span><br><span class="line">        <span class="comment">/** 关键代码</span></span><br><span class="line"><span class="comment">         *  子进程写管道完毕后再执行父进程读管道, 所以需要用wait函数等待子进程返回后再操作</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="type">int</span> status;</span><br><span class="line">        waitpid(pid, &amp;status, <span class="number">0</span>);       <span class="comment">// 等待子进程返回</span></span><br><span class="line">        <span class="type">int</span> err = WEXITSTATUS(status);  <span class="comment">// 读取子进程的返回码</span></span><br><span class="line">        <span class="keyword">if</span> (err) &#123; </span><br><span class="line">            <span class="built_in">printf</span>(<span class="string">&quot;Error: %s\n&quot;</span>, strerror(err));</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        close(pd[<span class="number">1</span>]);                    <span class="comment">// 关闭父进程管道的写端</span></span><br><span class="line">        dup2(pd[<span class="number">0</span>], STDIN_FILENO);       <span class="comment">// 管道读端读到的重定向为标准输入</span></span><br><span class="line">        parse(inputBuf);</span><br><span class="line">        execvp(argv[<span class="number">0</span>], argv);</span><br><span class="line">        <span class="keyword">if</span> (pd[<span class="number">0</span>] != STDIN_FILENO) &#123;</span><br><span class="line">            close(pd[<span class="number">0</span>]);</span><br><span class="line">        &#125;       </span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="type">int</span> <span class="title function_">commandInBackground</span><span class="params">(<span class="type">char</span> buf[BUFFSIZE])</span> &#123;</span><br><span class="line">    <span class="type">char</span> backgroundBuf[<span class="built_in">strlen</span>(buf)];</span><br><span class="line">    <span class="built_in">memset</span>(backgroundBuf, <span class="number">0x00</span>, <span class="built_in">strlen</span>(buf));</span><br><span class="line">    <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; <span class="built_in">strlen</span>(buf); i++) &#123;</span><br><span class="line">        backgroundBuf[i] = buf[i];</span><br><span class="line">        <span class="keyword">if</span> (buf[i] == <span class="string">&#x27;&amp;&#x27;</span>) &#123;</span><br><span class="line">            backgroundBuf[i] = <span class="string">&#x27;\0&#x27;</span>;</span><br><span class="line">            backgroundBuf[i - <span class="number">1</span>] = <span class="string">&#x27;\0&#x27;</span>;</span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="type">pid_t</span> pid;</span><br><span class="line">    pid = fork();</span><br><span class="line">    <span class="keyword">if</span> (pid &lt; <span class="number">0</span>) &#123;</span><br><span class="line">        perror(<span class="string">&quot;fork()&quot;</span>);</span><br><span class="line">        <span class="built_in">exit</span>(<span class="number">1</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (pid == <span class="number">0</span>) &#123;</span><br><span class="line">        <span class="comment">// 将stdin、stdout、stderr重定向到/dev/null</span></span><br><span class="line">        freopen( <span class="string">&quot;/dev/null&quot;</span>, <span class="string">&quot;w&quot;</span>, <span class="built_in">stdout</span> );</span><br><span class="line">        freopen( <span class="string">&quot;/dev/null&quot;</span>, <span class="string">&quot;r&quot;</span>, <span class="built_in">stdin</span> ); </span><br><span class="line">        signal(SIGCHLD,SIG_IGN);</span><br><span class="line">        parse(backgroundBuf);</span><br><span class="line">        execvp(argv[<span class="number">0</span>], argv);</span><br><span class="line">        <span class="built_in">printf</span>(<span class="string">&quot;%s: 命令输入错误\n&quot;</span>, argv[<span class="number">0</span>]);</span><br><span class="line">        <span class="comment">// exit函数终止当前进程, 括号内参数为1时, 会像操作系统报告该进程因异常而终止</span></span><br><span class="line">        <span class="built_in">exit</span>(<span class="number">1</span>);</span><br><span class="line">    &#125;<span class="keyword">else</span> &#123;</span><br><span class="line">        <span class="built_in">exit</span>(<span class="number">0</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="type">void</span> <span class="title function_">myTop</span><span class="params">()</span> &#123;</span><br><span class="line">    FILE *fp = <span class="literal">NULL</span>;                    <span class="comment">// 文件指针</span></span><br><span class="line">    <span class="type">char</span> buff[<span class="number">255</span>];</span><br><span class="line"></span><br><span class="line">    <span class="comment">/* 获取内容一: </span></span><br><span class="line"><span class="comment">       总体内存大小，</span></span><br><span class="line"><span class="comment">       空闲内存大小，</span></span><br><span class="line"><span class="comment">       缓存大小。 */</span></span><br><span class="line">    fp = fopen(<span class="string">&quot;/proc/meminfo&quot;</span>, <span class="string">&quot;r&quot;</span>);   <span class="comment">// 以只读方式打开meminfo文件</span></span><br><span class="line">    fgets(buff, <span class="number">255</span>, (FILE*)fp);        <span class="comment">// 读取meminfo文件内容进buff</span></span><br><span class="line">    fclose(fp);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 获取 pagesize</span></span><br><span class="line">    <span class="type">int</span> i = <span class="number">0</span>, pagesize = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">while</span> (buff[i] != <span class="string">&#x27; &#x27;</span>) &#123;</span><br><span class="line">        pagesize = <span class="number">10</span> * pagesize + buff[i] - <span class="number">48</span>;</span><br><span class="line">        i++;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 获取 页总数 total</span></span><br><span class="line">    i++;</span><br><span class="line">    <span class="type">int</span> total = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">while</span> (buff[i] != <span class="string">&#x27; &#x27;</span>) &#123;</span><br><span class="line">        total = <span class="number">10</span> * total + buff[i] - <span class="number">48</span>;</span><br><span class="line">        i++;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 获取空闲页数 free</span></span><br><span class="line">    i++;</span><br><span class="line">    <span class="type">int</span> <span class="built_in">free</span> = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">while</span> (buff[i] != <span class="string">&#x27; &#x27;</span>) &#123;</span><br><span class="line">        <span class="built_in">free</span> = <span class="number">10</span> * <span class="built_in">free</span> + buff[i] - <span class="number">48</span>;</span><br><span class="line">        i++;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 获取最大页数量largest</span></span><br><span class="line">    i++;</span><br><span class="line">    <span class="type">int</span> largest = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">while</span> (buff[i] != <span class="string">&#x27; &#x27;</span>) &#123;</span><br><span class="line">        largest = <span class="number">10</span> * largest + buff[i] - <span class="number">48</span>;</span><br><span class="line">        i++;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 获取缓存页数量 cached</span></span><br><span class="line">    i++;</span><br><span class="line">    <span class="type">int</span> cached = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">while</span> (buff[i] &gt;= <span class="string">&#x27;0&#x27;</span> &amp;&amp; buff[i] &lt;= <span class="string">&#x27;9&#x27;</span>) &#123;</span><br><span class="line">        cached = <span class="number">10</span> * cached + buff[i] - <span class="number">48</span>;</span><br><span class="line">        i++;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 总体内存大小 = (pagesize * total) / 1024 单位 KB</span></span><br><span class="line">    <span class="type">int</span> totalMemory  = pagesize / <span class="number">1024</span> * total;</span><br><span class="line">    <span class="comment">// 空闲内存大小 = pagesize * free) / 1024 单位 KB</span></span><br><span class="line">    <span class="type">int</span> freeMemory   = pagesize / <span class="number">1024</span> * <span class="built_in">free</span>;</span><br><span class="line">    <span class="comment">// 缓存大小    = (pagesize * cached) / 1024 单位 KB</span></span><br><span class="line">    <span class="type">int</span> cachedMemory = pagesize / <span class="number">1024</span> * cached;</span><br><span class="line"></span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;totalMemory  is %d KB\n&quot;</span>, totalMemory);</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;freeMemory   is %d KB\n&quot;</span>, freeMemory);</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;cachedMemory is %d KB\n&quot;</span>, cachedMemory);</span><br><span class="line"></span><br><span class="line">    <span class="comment">/* 2. 获取内容2</span></span><br><span class="line"><span class="comment">        进程和任务数量</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    fp = fopen(<span class="string">&quot;/proc/kinfo&quot;</span>, <span class="string">&quot;r&quot;</span>);     <span class="comment">// 以只读方式打开meminfo文件</span></span><br><span class="line">    <span class="built_in">memset</span>(buff, <span class="number">0x00</span>, <span class="number">255</span>);            <span class="comment">// 格式化buff字符串</span></span><br><span class="line">    fgets(buff, <span class="number">255</span>, (FILE*)fp);        <span class="comment">// 读取meminfo文件内容进buff</span></span><br><span class="line">    fclose(fp);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 获取进程数量</span></span><br><span class="line">    <span class="type">int</span> processNumber = <span class="number">0</span>;</span><br><span class="line">    i = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">while</span> (buff[i] != <span class="string">&#x27; &#x27;</span>) &#123;</span><br><span class="line">        processNumber = <span class="number">10</span> * processNumber + buff[i] - <span class="number">48</span>;</span><br><span class="line">        i++;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;processNumber = %d\n&quot;</span>, processNumber);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 获取任务数量</span></span><br><span class="line">    i++;</span><br><span class="line">    <span class="type">int</span> tasksNumber = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">while</span> (buff[i] &gt;= <span class="string">&#x27;0&#x27;</span> &amp;&amp; buff[i] &lt;= <span class="string">&#x27;9&#x27;</span>) &#123;</span><br><span class="line">        tasksNumber = <span class="number">10</span> * tasksNumber + buff[i] - <span class="number">48</span>;</span><br><span class="line">        i++;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;tasksNumber = %d\n&quot;</span>, tasksNumber);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="comment">// /* 3. 获取psinfo中的内容 */</span></span><br><span class="line">    DIR *d;</span><br><span class="line">    <span class="class"><span class="keyword">struct</span> <span class="title">dirent</span> *<span class="title">dir</span>;</span></span><br><span class="line">    d = opendir(<span class="string">&quot;/proc&quot;</span>);</span><br><span class="line">    <span class="type">int</span> totalTicks = <span class="number">0</span>, freeTicks = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">if</span> (d) &#123;</span><br><span class="line">        <span class="keyword">while</span> ((dir = readdir(d)) != <span class="literal">NULL</span>) &#123;                   <span class="comment">// 遍历proc文件夹</span></span><br><span class="line">            <span class="keyword">if</span> (<span class="built_in">strcmp</span>(dir-&gt;d_name, <span class="string">&quot;.&quot;</span>) != <span class="number">0</span> &amp;&amp; </span><br><span class="line">                <span class="built_in">strcmp</span>(dir-&gt;d_name, <span class="string">&quot;..&quot;</span>) != <span class="number">0</span>) &#123;</span><br><span class="line">                    <span class="type">char</span> path[<span class="number">255</span>];</span><br><span class="line">                    <span class="built_in">memset</span>(path, <span class="number">0x00</span>, <span class="number">255</span>);</span><br><span class="line">                    <span class="built_in">strcpy</span>(path, <span class="string">&quot;/proc/&quot;</span>);</span><br><span class="line">                    <span class="built_in">strcat</span>(path, dir-&gt;d_name);          <span class="comment">// 连接成为完成路径名</span></span><br><span class="line">                    <span class="class"><span class="keyword">struct</span> <span class="title">stat</span> <span class="title">s</span>;</span></span><br><span class="line">                    <span class="keyword">if</span> (stat (path, &amp;s) == <span class="number">0</span>) &#123;</span><br><span class="line">                        <span class="keyword">if</span> (S_ISDIR(s.st_mode)) &#123;       <span class="comment">// 判断为目录</span></span><br><span class="line">                            <span class="built_in">strcat</span>(path, <span class="string">&quot;/psinfo&quot;</span>);</span><br><span class="line"></span><br><span class="line">                            FILE* fp = fopen(path, <span class="string">&quot;r&quot;</span>);</span><br><span class="line">                            <span class="type">char</span> buf[<span class="number">255</span>];</span><br><span class="line">                            <span class="built_in">memset</span>(buf, <span class="number">0x00</span>, <span class="number">255</span>);</span><br><span class="line">                            fgets(buf, <span class="number">255</span>, (FILE*)fp);</span><br><span class="line">                            fclose(fp);</span><br><span class="line"></span><br><span class="line">                            <span class="comment">// 获取ticks和进程状态</span></span><br><span class="line">                            <span class="type">int</span> j = <span class="number">0</span>;</span><br><span class="line">                            <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; <span class="number">4</span>;) &#123;</span><br><span class="line">                                <span class="keyword">for</span> (j = <span class="number">0</span>; j &lt; <span class="number">255</span>; j++) &#123;</span><br><span class="line">                                    <span class="keyword">if</span> (i &gt;= <span class="number">4</span>) <span class="keyword">break</span>;</span><br><span class="line">                                    <span class="keyword">if</span> (buf[j] == <span class="string">&#x27; &#x27;</span>) i++;</span><br><span class="line">                                &#125;</span><br><span class="line">                            &#125;</span><br><span class="line">                            <span class="comment">// 循环结束, buf[j]为进程的状态, 共有S, W, R三种状态.</span></span><br><span class="line">                            <span class="type">int</span> k = j + <span class="number">1</span>;</span><br><span class="line">                            <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; <span class="number">3</span>;) &#123;               <span class="comment">// 循环结束后k指向ticks位置</span></span><br><span class="line">                                <span class="keyword">for</span> (k = j + <span class="number">1</span>; k &lt; <span class="number">255</span>; k++) &#123;</span><br><span class="line">                                    <span class="keyword">if</span> (i &gt;= <span class="number">3</span>) <span class="keyword">break</span>;</span><br><span class="line">                                    <span class="keyword">if</span> (buf[k] == <span class="string">&#x27; &#x27;</span>) i++;</span><br><span class="line">                                &#125;</span><br><span class="line">                            &#125;</span><br><span class="line">                            <span class="type">int</span> processTick = <span class="number">0</span>;</span><br><span class="line">                            <span class="keyword">while</span> (buf[k] != <span class="string">&#x27; &#x27;</span>) &#123;</span><br><span class="line">                                processTick = <span class="number">10</span> * processTick + buff[k] - <span class="number">48</span>;</span><br><span class="line">                                k++;</span><br><span class="line">                            &#125;</span><br><span class="line">                            totalTicks += processTick;</span><br><span class="line">                            <span class="keyword">if</span> (buf[j] != <span class="string">&#x27;R&#x27;</span>) &#123;</span><br><span class="line">                                freeTicks += processTick;</span><br><span class="line">                            &#125;</span><br><span class="line">                        &#125;<span class="keyword">else</span> <span class="keyword">continue</span>;</span><br><span class="line">                    &#125;<span class="keyword">else</span> <span class="keyword">continue</span>;</span><br><span class="line">                &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;CPU states: %.2lf%% used,\t%.2lf%% idle&quot;</span>,</span><br><span class="line">           (<span class="type">double</span>)((totalTicks - freeTicks) * <span class="number">100</span>) / (<span class="type">double</span>)totalTicks,</span><br><span class="line">           (<span class="type">double</span>)(freeTicks * <span class="number">100</span>) / (<span class="type">double</span>)totalTicks);</span><br><span class="line">    <span class="keyword">return</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">/* main函数 */</span></span><br><span class="line"><span class="type">int</span> <span class="title function_">main</span><span class="params">()</span> &#123;</span><br><span class="line">    <span class="comment">// while循环</span></span><br><span class="line">    <span class="keyword">while</span>(<span class="number">1</span>) &#123;</span><br><span class="line">        <span class="built_in">printf</span>(<span class="string">&quot;ljx@ljx-virtual-machine$ &quot;</span>);</span><br><span class="line">        <span class="comment">// 输入字符存入buf数组, 如果输入字符数为0, 则跳过此次循环</span></span><br><span class="line">        <span class="keyword">if</span> (get_input(buf) == <span class="number">0</span>)</span><br><span class="line">            <span class="keyword">continue</span>;</span><br><span class="line">        <span class="built_in">strcpy</span>(history[commandNum++], buf);</span><br><span class="line">        <span class="built_in">strcpy</span>(backupBuf, buf);</span><br><span class="line">        parse(buf);</span><br><span class="line">        do_cmd(argc, argv);</span><br><span class="line">        argc = <span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>
</article><div class="post-copyright"><div class="post-copyright__author"><span class="post-copyright-meta"><i class="fas fa-circle-user fa-fw"></i>文章作者: </span><span class="post-copyright-info"><a href="http://www.lijunxi.site">Jixer</a></span></div><div class="post-copyright__type"><span class="post-copyright-meta"><i class="fas fa-square-arrow-up-right fa-fw"></i>文章链接: </span><span class="post-copyright-info"><a href="http://www.lijunxi.site/posts/2960345248/">http://www.lijunxi.site/posts/2960345248/</a></span></div><div class="post-copyright__notice"><span class="post-copyright-meta"><i class="fas fa-circle-exclamation fa-fw"></i>版权声明: </span><span class="post-copyright-info">本博客所有文章除特别声明外，均采用 <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/" target="_blank">CC BY-NC-SA 4.0</a> 许可协议。转载请注明来自 <a href="http://www.lijunxi.site" target="_blank">Jixer的小屋</a>！</span></div></div><div class="tag_share"><div class="post-meta__tag-list"><a class="post-meta__tags" href="/tags/Linux/">Linux</a></div><div class="post_share"><div class="social-share" data-image="https://q1.qlogo.cn/g?b=qq&amp;nk=2770063826&amp;s=640" data-sites="facebook,twitter,wechat,weibo,qq"></div><link rel="stylesheet" href="/pluginsSrc/butterfly-extsrc/sharejs/dist/css/share.min.css?v=1.1.3" media="print" onload="this.media='all'"><script src="/pluginsSrc/butterfly-extsrc/sharejs/dist/js/social-share.min.js?v=1.1.3" defer></script></div></div><nav class="pagination-post" id="pagination"><div class="prev-post pull-left"><a href="/posts/3169960946/" title="数据结构与算法大作业"><div class="cover" style="background: var(--default-bg-color)"></div><div class="pagination-info"><div class="label">上一篇</div><div class="prev_info">数据结构与算法大作业</div></div></a></div><div class="next-post pull-right"><a href="/posts/1476420007/" title="SpringCloud学习笔记"><div class="cover" style="background: var(--default-bg-color)"></div><div class="pagination-info"><div class="label">下一篇</div><div class="next_info">SpringCloud学习笔记</div></div></a></div></nav></div><div class="aside-content" id="aside-content"><div class="card-widget card-info"><div class="is-center"><div class="avatar-img"><img src="" data-original="https://q1.qlogo.cn/g?b=qq&amp;nk=2770063826&amp;s=640" onerror="this.onerror=null;this.src='/img/friend_404.gif'" alt="avatar"/></div><div class="author-info__name">Jixer</div><div class="author-info__description"></div></div><div class="card-info-data site-data is-center"><a href="/archives/"><div class="headline">文章</div><div class="length-num">52</div></a><a href="/tags/"><div class="headline">标签</div><div class="length-num">19</div></a><a href="/categories/"><div class="headline">分类</div><div class="length-num">7</div></a></div><a id="card-info-btn" target="_blank" rel="noopener" href="https://github.com/2770063826"><i class="fab fa-github"></i><span>Follow Me</span></a></div><div class="card-widget card-announcement"><div class="item-headline"><i class="fas fa-bullhorn fa-shake"></i><span>公告</span></div><div class="announcement_content"></div></div><div class="sticky_layout"><div class="card-widget" id="card-toc"><div class="item-headline"><i class="fas fa-stream"></i><span>目录</span><span class="toc-percentage"></span></div><div class="toc-content"><ol class="toc"><li class="toc-item toc-level-2"><a class="toc-link" href="#Java%E7%89%88%E6%9C%AC"><span class="toc-text">Java版本</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#C%E7%89%88%E6%9C%AC"><span class="toc-text">C版本</span></a></li></ol></div></div><div class="card-widget card-recent-post"><div class="item-headline"><i class="fas fa-history"></i><span>最新文章</span></div><div class="aside-list"><div class="aside-list-item no-cover"><div class="content"><a class="title" href="/posts/2029624507/" title="2022年算法队选拔赛">2022年算法队选拔赛</a><time datetime="2024-05-09T15:00:27.000Z" title="发表于 2024-05-09 23:00:27">2024-05-09</time></div></div><div class="aside-list-item no-cover"><div class="content"><a class="title" href="/posts/1978524057/" title="牛客小白月赛84">牛客小白月赛84</a><time datetime="2024-05-08T14:40:35.000Z" title="发表于 2024-05-08 22:40:35">2024-05-08</time></div></div><div class="aside-list-item no-cover"><div class="content"><a class="title" href="/posts/131339317/" title="软件测试资料">软件测试资料</a><time datetime="2024-05-07T03:12:52.000Z" title="发表于 2024-05-07 11:12:52">2024-05-07</time></div></div><div class="aside-list-item no-cover"><div class="content"><a class="title" href="/posts/2394234105/" title="第十四届蓝桥杯B组国赛">第十四届蓝桥杯B组国赛</a><time datetime="2024-05-05T13:40:15.000Z" title="发表于 2024-05-05 21:40:15">2024-05-05</time></div></div><div class="aside-list-item no-cover"><div class="content"><a class="title" href="/posts/1405472621/" title="Leetcode第396场周赛">Leetcode第396场周赛</a><time datetime="2024-05-05T03:58:25.000Z" title="发表于 2024-05-05 11:58:25">2024-05-05</time></div></div></div></div></div></div></main><footer id="footer"><div id="footer-wrap"><div class="copyright">&copy;2024 By Jixer</div><div class="framework-info"><span>框架 </span><a target="_blank" rel="noopener" href="https://hexo.io">Hexo</a><span class="footer-separator">|</span><span>主题 </span><a target="_blank" rel="noopener" href="https://github.com/jerryc127/hexo-theme-butterfly">Butterfly</a></div><div class="footer_custom_text"><a href="https://beian.miit.gov.cn/#/Integrated/index" style="color:white" target="_blank">蜀ICP备2022009955号-1</a></div></div></footer></div><div id="rightside"><div id="rightside-config-hide"><button id="readmode" type="button" title="阅读模式"><i class="fas fa-book-open"></i></button><button id="darkmode" type="button" title="浅色和深色模式转换"><i class="fas fa-adjust"></i></button><button id="hide-aside-btn" type="button" title="单栏和双栏切换"><i class="fas fa-arrows-alt-h"></i></button></div><div id="rightside-config-show"><button id="rightside-config" type="button" title="设置"><i class="fas fa-cog fa-spin"></i></button><button class="close" id="mobile-toc-button" type="button" title="目录"><i class="fas fa-list-ul"></i></button><button id="go-up" type="button" title="回到顶部"><span class="scroll-percent"></span><i class="fas fa-arrow-up"></i></button></div></div><div><script src="/js/utils.js?v=4.13.0"></script><script src="/js/main.js?v=4.13.0"></script><script src="/pluginsSrc/@fancyapps/ui/dist/fancybox/fancybox.umd.js?v=5.0.33"></script><div class="js-pjax"></div><script src="/js/custom-fancybox-umd-min.js"></script><script src="/js/custom-busuanzi-pure-mini.js"></script><script src="/js/Valine.min.js"></script><script src="/js/custom-social-share.min.js"></script><script src="/js/custom-typed-umd-min.js"></script><script src="/js/av-min.js"></script><script async data-pjax src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script><div id="local-search"><div class="search-dialog"><nav class="search-nav"><span class="search-dialog-title">搜索</span><span id="loading-status"></span><button class="search-close-button"><i class="fas fa-times"></i></button></nav><div class="is-center" id="loading-database"><i class="fas fa-spinner fa-pulse"></i><span>  数据库加载中</span></div><div class="search-wrap"><div id="local-search-input"><div class="local-search-box"><input class="local-search-box--input" placeholder="搜索文章" type="text"/></div></div><hr/><div id="local-search-results"></div><div id="local-search-stats-wrap"></div></div></div><div id="search-mask"></div><script src="/js/search/local-search.js?v=4.13.0"></script></div></div>
        <style>
            [bg-lazy] {
                background-image: none !important;
                background-color: #eee !important;
            }
        </style>
        <script>
            window.imageLazyLoadSetting = {
                isSPA: false,
                preloadRatio: 1,
                processImages: null,
            };
        </script><script>window.addEventListener("load",function(){var t=/\.(gif|jpg|jpeg|tiff|png)$/i,r=/^data:image\/[a-z]+;base64,/;Array.prototype.slice.call(document.querySelectorAll("img[data-original]")).forEach(function(a){var e=a.parentNode;"A"===e.tagName&&(e.href.match(t)||e.href.match(r))&&(e.href=a.dataset.original)})});</script><script>!function(r){r.imageLazyLoadSetting.processImages=t;var e=r.imageLazyLoadSetting.isSPA,n=r.imageLazyLoadSetting.preloadRatio||1,c=a();function a(){var t=Array.prototype.slice.call(document.querySelectorAll("img[data-original]")),e=Array.prototype.slice.call(document.querySelectorAll("[bg-lazy]"));return t.concat(e)}function t(){e&&(c=a());for(var t,o=0;o<c.length;o++)0<=(t=(t=c[o]).getBoundingClientRect()).bottom&&0<=t.left&&t.top<=(r.innerHeight*n||document.documentElement.clientHeight*n)&&function(){var t,e,n,a,i=c[o];e=function(){c=c.filter(function(t){return i!==t}),r.imageLazyLoadSetting.onImageLoaded&&r.imageLazyLoadSetting.onImageLoaded(i)},(t=i).hasAttribute("bg-lazy")?(t.removeAttribute("bg-lazy"),e&&e()):(n=new Image,a=t.getAttribute("data-original"),n.onload=function(){t.src=a,t.removeAttribute("data-original"),e&&e()},t.src!==a&&(n.src=a))}()}function i(){clearTimeout(t.tId),t.tId=setTimeout(t,500)}t(),document.addEventListener("scroll",i),r.addEventListener("resize",i),r.addEventListener("orientationchange",i)}(this);</script></body></html>